Can Winelib link a DLL directly to the ELF executable? - c++

There is a DLL (no source code, but no fancy stuff expected inside, hopefully). Going to write a Linux application to use it. So, GNU all the way: native Linux gcc/gdb/ELF, etc.
I've found here on SO some solutions: with WineLib it's possible to write a code that have access to the win32 LoadLibrary function, and that code still compiles into ELF binary. A bit of API forwarding and here is a *.so file that calls LoadLibrary on the dll and exposes its functions.
Is it correct?
Is it possible to automate it? Is there an example with winedump and winegcc that are probably the tools for this job?

Sounds all perfectly reasonable. The DLL format is properly ancient, and not excessively complex (it had to work on the original 8086 CPU, and it got simpler with 32 bits Windows). Code is just that, x86 instructions, and data may be even more boring.
However, it sounds also very specialized, which probably explains why I've never heard of an actual implementation of this idea.

Related

Read ini file in C++ using 64 compiler

I want to read ini file in C++ using 64 bit compiler of visual studio, and GetPrivateProfileString() doesn't work for 64 bit compiler it just work for Win32.
Is there any way to read such file other than using GetPrivateProfileString()??
GetPrivateProfileString() doesn't work for 64 bit compiler it just work for Win32.
This is absolutely incorrect. Virtually all of the Win32 functions are available as 64-bit versions, and GetPrivateProfileString is no exception. If you are unable to make it work, then the code that you have written is wrong. Unfortunately, you didn't show that code, so we can't tell you how to fix it.
Do make sure that you are passing a fully-qualified path to the file when trying to call this function! Relative paths will not have the desired effect.
However, you should probably not be using GetPrivateProfileString anyway. As the documentation says:
Note This function is provided only for compatibility with 16-bit Windows-based applications. Applications should store initialization information in the registry.
INI files are still sometimes a reasonable choice—e.g., as settings files for "portable" applications for which you do not want to modify the registry—but you should still not use the Windows Get/SetPrivateProfile* API functions to read and write these files. They are very old, ported directly from 16-bit Windows, and contain lots of unexpected behavior for backwards-compatibility reasons. They are also slow and offer very limited features.
Although there are many alternatives, my personal recommendation would be the SimpleINI library. This is cross-platform, uses the C++ standard library, and has been released under the MIT license. Just drop it in and start using it. I works well; I use it in one of my MFC applications.
You could also use Boost to read INI files.
I can't comment yet, so I'm answering.
GetPrivateProfileString() works perfectly for me under Visual Studio 2015 on any platform, Win32 as well as x64, and on any charset UNICODE or MBCS.
Double check your code, or post it so we can have a look.

Releasing a program

So I made a c++ console game. Now I'd like to "release" the game. I want to only give the .exe file and not the code. How do i go about this. I'd like to make sure it will run on all windows devices.
I used the following headers-
iostream
windows.h
MMSystem.h
conio.h
fstream
ctime
string
string.h
*I used namespace std
*i used code::blocks 13.12 with mingw
& I used the following library-
libwinmm.a
Thank you in advance
EDIT
There are many different ways of installing applications. You could go with an installer like Inno or just go with a regular ZIP file. Some programs can even be standalone by packaging all resources within the executable, but this is not an easy option to my knowledge for C++.
I suppose the most basic way is to create different builds for different architectures with static libraries and then find any other DLLs specific to that architecture and bundle it together in one folder. Supporting x86/x86-64/ARM should be enough for most purposes. I do know that LLVM/Clang and GCC should have extensive support for many architectures, and if need be, you should be able to download the source code of the libraries you use and then compile them for each architecture you plan to support as well as the compilation options you need to compile to each one.
A virtual machine can also be helpful for this cross-compilation and compatibility testing.
tldr; Get all the libraries you need in either static or dynamic (DLL) format. Check that they are of the right architecture (x86 programs/code will not run on MIPS and vice versa). Get all your resources. Get a virtual machine, and then test your program on it. Keep testing until all the dependency problems go away.
Note: when I did this, I actually had some compatibility issues with, of all things, MinGW-w64. Just a note; you may need some DLLs from MinGW, or, if you're using Cygwin, of course you need the Cygwin DLL. I don't know much about MSVC, but I would assume that even they have DLLs needed on some level if you decide to support an outdated Windows OS.

Is it possible to use same DLL for clients using both Windows and Linux

I am looking to create a C++ library that can be used by both Linux and Windows clients. The OS specific functionality will be hooked up by the client by implementing the interfaces provided by the library.
Is this possible to achieve? Do I need to recompile the C++ project again in linux.
P.S: I am using CodeBlocks IDE
The short answer is no, you still need to compile your library for each targetted platform -- however, assuming your code is written such that it is cross-platform, you can set up your build to target both Windows and Linux environments with little fuss. I do this now using CMake to generate both Visual Studio projects for Windows environments and Makefiles for Linux environments.
I'm pretty confident that Linux will not accept a .dll :) And yes, you will need to recompile. Unless you run windows as a virtual machine under linux which sort of preempts the question.
It certainly cannot be the same binary file: shared objects ELF format on Linux, DLL "PE" format on Windows. And dynamic loading has different semantics on both systems. See Levine's linker and loader book for details.
You could, if done carefully, have the same source code giving the two different files (the DLL on Windows, the dynamic shared object on Linux).
But you probably would need some conditional compilation tricks like #ifdef WINDOWS etc...
You might use libraries providing you a common abstraction for such things. For instance, both GTK/Glib and Qt have some mechanism giving a common abstraction of dynamically linked (or dynamically loaded - ie dlopen-ed) libraries.
You probably want to read the Program Library Howto (at least for Linux).

Same binary code on Windows and Linux (x86)

I want to compile a bunch of C++ files into raw machine code and the run it with a platform-dependent starter written in C. Something like
fread(buffer, 1, len, file);
a=((*int(*)(int))buffer)(b);
How can I tell g++ to output raw code?
Will function calls work? How can I make it work?
I think the calling conventions of Linux and Windows differ. Is this a problem? How can I solve it?
EDIT: I know that PE and ELF prevent the DIRECT starting of the executable. But that's what I have the starter for.
There is one (relatively) simple way of achieving some of this, and that's called "position independent code". See your compiler documentation for this.
Meaning you can compile some sources into a binary which will execute no matter where in the address space you place it. If you have such a piece of x86 binary code in a file and mmap() it (or the Windows equivalent) it is possible to invoke it from both Linux and Windows.
Limitations already mentioned are of course still present - namely, the binary code must restrict itself to using a calling convention that's identical on both platforms / can be represented on both platforms (for 32bit x86, that'd be passing args on the stack and returning values in EAX), and of course the code must be fully self-contained - no DLL function calls as resolving these is system dependent, no system calls either.
I.e.:
You need position-independent code
You must create self-contained code without any external dependencies
You must extract the machine code from the object file.
Then mmap() that file, initialize a function pointer, and (*myblob)(someArgs) may do.
If you're using gcc, the -ffreestanding -nostdinc -fPIC options should give you most of what you want regarding the first two, then use objdump to extract the binary blob from the ELF object file afterwards.
Theoretically, some of this is achievable. However there are so many gotchas along the way that it's not really a practical solution for anything.
System call formats are totally incompatible
DEP will prevent data executing as code
Memory layouts are different
You need to effectively dynamically 'relink' the code before you can run it.
.. and so forth...
The same executable cannot be run on both Windows and Linux.
You write your code platform independently (STL, Boost & Qt can help with this), then compile in G++ on Linux to output a linux-binary, and similarly on a compiler on the windows platform.
EDIT: Also, perhaps these two posts might help you:
One
Two
Why don't you take a look at wine? It's for using windows executables on Linux. Another solution for that is using Java or .NET bytecode.
You can run .NET executables on Linux (requires mono runtime)
Also have a look at Agner's objconv (disassembling, converting PE executable to ELF etc.)
http://www.agner.org/optimize/#objconv
Someone actually figured this out. It’s called αcτµαlly pδrταblε εxεcµταblε (APE) and you use the Cosmopolitan C library. The gist is that there’s a way to cause Windows PE executable headers to be ignored and treated as a shell script. Same goes for MacOS allowing you to define a single executable. Additionally, they also figured out how to smuggle ZIP into it so that it can incrementally compress the various sections of the file / decompress on run.
https://justine.lol/ape.html
https://github.com/jart/cosmopolitan
Example of a single identical Lua binary running on Linux and Windows:
https://ahgamut.github.io/2021/02/27/ape-cosmo/
Doing such a thing would be rather complicated. It isn't just a matter of the cpu commands being issued, the compiler has dependencies on many libraries that will be linked into the code. Those libraries will have to match at run-time or it won't work.
For example, the STL library is a series of templates and library functions. The compiler will inline some constructs and call the library for others. It'd have to be the exact same library to work.
Now, in theory you could avoid using any library and just write in fundamentals, but even there the compiler may make assumptions about how they work, what type of data alignment is involved, calling convention, etc.
Don't get me wrong, it can work. Look at the WINE project and other native drivers from windows being used on Linux. I'm just saying it isn't something you can quickly and easily do.
Far better would be to recompile on each platform.
That is achievable only if you have WINE available on your Linux system. Otherwise, the difference in the executable file format will prevent you from running Windows code on Linux.

How to load a c++ dll file into Matlab

I have a C++ dll file that uses a lot of other c++ librarys (IPP, Opencv +++) that I need to load into matlab. How can I do this?
I have tried loadlibrary and mex. The load library does not work.
The mex finds the linux things (platform independent library) and tries to include them. And that does not work.
Does anyone have any good ideas?
loadlibrary should work. I use it all the time to call functions from dlls written in C++ with C wrappers.
What errors are you getting when you try to use loadlibrary?
Make sure that the exported functions of the dll are C functions, not C++ functions. If not, then write C wrappers.
More info on exactly what you are doing when using loadlibrary would be helpful.
As mentioned by others, you should first wrap your C++ library as a C library - mathworks used to advise not to use C++ code directly in mex (dlopening C++ core directly is complicated), maybe it is still true.
Your description is quite unclear, too: what do you mean by "mex finds the linux thing", but that does not work. Saying that it does not work is not helpful: the exact commands and error message are.
You could go for the Java approach (since Matlab runs on a JRE and can access Java objects/methods -- just be aware that the Matlab JRE is not as up-to-date as the latest JRE, the one I'm running uses Java 1.5) and use JNA to access your DLL.
Or, if you wrote the top-level DLL, you could go for the COM/ActiveX approach.
I've had good success architecting the interface to my C++ functions as COM/ActiveX libraries -- you don't have to bother with that .h stuff.
See the External Interfaces guide on COM clients, particularly the part about managing/converting data.
It would be extra work to add the COM/ActiveX layer, but would make your library more portable within the Windows world and probably more easily used in MATLAB.
If you have a lot of function calls to your DLL, the COM/ActiveX approach might be faster (not sure), but otherwise I think the JNA approach would be easier.