Cause of "entry point could not be located" in unrelated DLL? - c

Before you dismiss this question as a repeat, this question is different than the many other similar questions on SO because the function in the error message is completely unrelated to the DLL.
The app and version info
I've got a 32-bit app in Visual Studio 2008 RTM which uses a MATLAB Compiler 4.17 (R2012a) generated DLL, Glib (2.32.4, binaries from GStreamer SDK 2012.9 32-bit), and Qt (4.8.3-vs2008), all running on Windows 7 x64 SP1.
The problem
The debug build runs fine, but in release I get the infamous The procedure entry point libXXXInitialize could not be located in the dynamic link library libglib-2.0-0.dll. The bizarre thing is that this libXXXInitialize function (which does exist in the MATLAB-based DLL) is totally unrelated to libglib-2.0-0.dll.
My research
I checked the obvious, ensuring that all libraries were compiled with VS2008 (except for GStreamer/GLib which is compiled with mingw, but since it's straight C there shouldn't be any issues), and checking for any other versions of the DLLs in the path. It seems like it must be some sort of linker problem.
Update 1
In Dependency Walker x86, it shows this libXXXInitialize as an unresolved (parent) import from not only libglib-2.0-0.dll, but all the other GLib/GStreamer DLLs as well, however the function is correctly resolved in the DLL where it should be found, libXXX.dll.
Update 2
I removed the call to libXXXInitialize and called mclInitializeApplication from the MATLAB Compiler Runtime, and now that function is failing to be resolved from the glib DLL.
However I found a solution (at least temporary), changing the linker options from /OPT:REF to /OPT:NOREF fixed the problem (so the linker "keeps functions and/or data that are never referenced). The bizarre thing is, I certainly use the mclInitializeApplication function explicitly, and if I turn on /VERBOSE:REF, it doesn't show it being removed.
Update 3
Finally found mention of this somewhere else, on the bugtracker for binutils. I found this in a MSVC2010 property sheet as part of the GStreamer SDK. Suggested workaround is what I'm already doing, disabling OptimizeReferences.
If anyone can tell me why this is happening, I'll mark it as the answer.

Related

How to work around the lack of InitOnceExecuteOnce in mingw (or mingw-w64) gcc?

I'm trying to build the OpenCL ICD Loader in mingw gcc - no problem to use mingw-w64 instead, it's just that mingw is what I have installed already. I don't use Visual Studio - I don't hate it, I know there's free versions, it's just not what I'm using.
The OpenCL ICD Loader doesn't build in mingw gcc. The main reason is because of lack of DirectX 10 and DirectX 11 support. But all the ICD Loader does is get a dispatch table (presumably from the OpenCL driver/whatever it loads) and provide functions that call through that dispatch table. Some minor changes to the conditional compilation in icd_dispatch.h and icd_dispatch.c can omit the relevant functions and remove the dependency (as already has to happen for Linux builds), and it actually looks like this may have been supported in the past - there's preprocessor symbols cl_khr_d3d10_sharing and cl_khr_d3d11_sharing already defined if relevant headers are included, they're just not being used to conditionally compile the relevant chunks of code.
So there's that and telling the code to omit DirectX10 and DirectX11 functionality in the first place (I just commented out a couple of header-file includes, though that's obviously not a real solution). But then there's one more problem...
The file icd_windows.c uses the Windows API function InitOnceExecuteOnce - MSDN docs here. mingw (and I think mingw-w64) doesn't support this function - the def file for Kernel32.dll lists it but neither the function nor the related identifiers INIT_ONCE, INIT_ONCE_STATIC_INIT and PINIT_ONCE are provided by header files.
The MSDN docs IMO don't explain this very well. It can't be essential (it didn't even exist before Vista) and it has something to do with safe initialization of DLLs, presumably in a multithreading context.
Unfortunately, if I don't really understand what it does, then I can't implement a workaround for its not being there.
Clearly this Windows API isn't specific to OpenCL, so presumably this is an issue that other people have run into for other projects. So is there a standard workaround for this?
Or failing that, can someone explain what is meant particularly by "synchronous one-time initialization"? Sorry if that's a dumb question, I don't have much experience of multithreaded, I'd have thought one-time initialization is just that, irrespective of synchronous vs. asynchronous - so long as a second thread can't re-enter the initialization, you don't want to initialize again, so there's nothing to do synchronously vs. asynchronously anyway.
Or does it mean that if another thread tries to call the initialization, it will wait for the already-running initialization to complete before it fails (or possibly succeeds without re-doing the initialization)?
I wasn't sure the opencl tag was appropriate, decided to include it because of the context, sorry if that was wrong.
I came across the same problem. You have to add following line at beginning of icd_windows.c, before all #includes:
#define _WIN32_WINNT 0x0600
This helps with missing InitOnceExecuteOnce declaration. I also had to modify CMakeLists.txt, replaced SHARED with STATIC in line 22 which is responsible for linking libOpenCL. I did this because linker complained about missing ld lib:
add_library (OpenCL STATIC ${OPENCL_ICD_LOADER_SOURCES})
After doing these two things I got libOpenCL.a in build subdir. Compilation continued and failed with some other error, but I ignored this. I took created lib and successfully used it to build simple OpenCL app which lists all available platforms, devices and their details.

Trying to solve WindowError 126 - module not found

Though this is my first question on the StackOverflow, I consider myself a long time member of the community.
Considering myself as a pre-intermediate programmer, I'll try to be as specific as possible.
I'm writing a Python package that uses a C dll to load image files with ctypes. I'm using Python 3.3.5 32bits version on Windows 8 x64. I had to build the dll from the C code. The dll is stb_image.h which is available in GitHub. I used Code::Blocks version 13.12 with the GCC compiler. The dll seems to have built fine.
By my definition, the dll is must be in the same folder as the py code file that wraps its functions, but when ctypes attempts to load the dll an exception is raised: the [in]famous WindowsError: [Error 126] Module not found.
I've found several similar questions and attempted to glean from their solutions by
adding the dll path via os.environ['PATH']
adding the dll path manually in the Path environment variable
changing the current working directory with os.chdir()
using the file module attribute to locate the library
none of these solved the issue
The stb_image library itself has no dependencies so I don't understand why windows can't find it since the dll is where it should be and the path addresses it's exact location. And, of course, there's a lot of other ways to get the job done: PyGame, pySFML (which also uses stb_image), PIL, PyPng, PySDL, you name it, but I'm doing this mostly for learning purposes.
At the writing of this question, something popped up in my head (which may or may not have any relation with the problem): whenever I compile and link programs with GCC and try to run them, I got a message box telling me that some dll (libgcc.dll or something like that) was not found. Could that be the reason Windows can't load stb_image.dll?
I tried everything my experience allowed me to do to solve it but it was not enough. Would you guys, please, give me a light on this?
PS.: Sorry for any bad english. I'm natural from Brazil.

Prevent linking of mallocr.o file within libc.a

This is for my company, so I'm leery of being too specific, but I'll try.
I am attempting to add support for some existing ANSI C code to our platform. I am using GCC 4.7.2 as well as the GNU linker. We use part of newlib, but also some other C libraries, specifically libc.a. The end goal of this is to get an EXE or ELF image (this is for a PowerPC architecture micro) to put into the micro's RAM. This is being done on Windows XP. I am simply using a batch file, not a build environment or toolchain.
One of my build errors is a multiple definition problem of malloc/free functions. The cmd window spits out the error that there are definitions of these in both malloc.o and mallocr.o. Both of these are within libc.a. I've been told the "r" in mallocr.o is for reentrancy. I've also been told our platform does not support reentrancy.
I'm trying to resolve this error by preventing the linking of mallocr.o from within libc.a. This is the part where I am lost, I don't know how to do this. Google hasn't turned up anything helpful, and I haven't found a question on this site yet that answers my problem. I don't know if this is even possible.
There is really no specific code snippet to include in this question. Below is the error from the cmd window. I've *'d out company specific things I am not comfortable sharing.
c:\***\platform\2_2_0_r2013-2_x86-32\tools\gcc_4_7_2\ppc\bin\..\powerpc-eabi\lib\libc.a(mallocr.o): In function `free':
mallocr.c:(.text+0x19c): multiple definition of `free'
c:\***\platform\2_2_0_r2013-2_x86-32\tools\gcc_4_7_2\ppc\bin\..\powerpc-eabi\lib\libc.a(malloc.o):malloc.c:(.text+0x28): first defined here
c:\***\platform\2_2_0_r2013-2_x86-32\tools\gcc_4_7_2\ppc\bin\..\powerpc-eabi\lib\libc.a(mallocr.o): In function `malloc':
mallocr.c:(.text+0x468): multiple definition of `malloc'
c:\***\platform\2_2_0_r2013-2_x86-32\tools\gcc_4_7_2\ppc\bin\..\powerpc-eabi\lib\libc.a(malloc.o):malloc.c:(.text+0x0): first defined here

How to create a working Executable file (.exe) from a C code

I have a C code created in Plato3. I want to create an exe file so I can share it with others.
Can someone please tell me how is this possible ?
I have tried sending the exe file that is created when normally compiled, but it crashes every time in runs on computers other than mine ...
Please help,
Thanks :)
[EDIT]
Program running on windows xp or vista .. same error :
Compiler used : SilverFrost (Fortran/C/C++) Development Studio (Plato3)
This application has failed to start
because salflibc.dll was not found,
reinstalling the application may fix
this problem
salflibc.dll is a library installed by the compiler on your development machine.
salf = Salford C Compiler, the obscure compiler included in Silverfrost
libc = C-language runtime support library, necessary for the basic functionality of any program
.dll = dynamically-linked library, i.e. a separate file from your .exe file
You might look for a compiler option that looks like "statically link runtime library;" this might eliminate the DLL dependency. However, if the compiler were capable of doing that, one would expect it to be the default, if not the only way.
However, I recall from the olden days of Classic Mac OS that sometimes DLL runtime libraries were used, the benefit being upgradability. Sometimes is a key word, though. (I suppose when the compiler vendor is the OS vendor, as with MSVC or Apple GCC, it is the norm, though.)
Another trick from that environment was to put the DLL in question in the application's directory and distribute it with the app. Typically runtime DLLs are licensed for free redistribution.
At the very least you have to make sure that the executable is running on the same architecture/operating system that it was compiled on.
Additionally, you need to make sure that any third party, or system libraries that are needed are available on the other systems too.
update
Based on the new information and error message you provide, it looks like you need to re-distribute the salflibc.dll
I would agree with other commenter's and suggest a different platform for development that is more mainstream, or supported.

How do I define HAVE_STDIO_H in VC++ 2005?

I just built an updated version of SDL.dll, an open-source C DLL that my Delphi project uses, with the Express edition of Visual C++ 2005. I dropped it in the folder with my EXE and tried to run it, but it won't load:
The procedure entry point SDL_RWFromFP could not be located in the dynamic
link library SDL.dll.
Now C never was my strong point, but I remember enough of it from college to try and track this one down. I went poking around in the source code to see what had happened to this function, and I found it grayed out, beneath a preprocessor directive:
#ifdef HAVE_STDIO_H
IIRC, STDIO is the standard C I/O library. I assume this means that it's not available. Anyone know why that would be and how to fix it? Is this a Visual C++ issue or an SDL one?
Most often in the Unix/Linux world, names like HAVE_STDIO_H indicate that the code has been 'autoconfiscated' (which is the official term used to describe the state of having been made to work with the 'autotools' such as 'autoconf'). In such a set up, the configure process would determine whether <stdio.h> was available and would set #define HAVE_STDIO_H 1 in the config.h file that it generates. The compilation would then discover that the platform has <stdio.h> and would compile the matching code (the stuff that is currently greyed out).
Adapting to your Windows environment, somewhat less than 100% confidently since there could be some other significance to HAVE_STDIO_H on Windows, you might decide that it would be OK to include -DHAVE_STDIO_H in the command line options when you run the compiler. Or you might create the config file by hand, and define -DHAVE_CONFIG_H (which is the normal way to indicate that configuration settings are in the file 'config.h'). In the 'config.h' file, you'd have #define HAVE_STDIO_H 1 as mentioned above.
Note: on Unix, you normally find a shell script called 'configure' which you run to create the config.h file. If you have Cygwin, there's an outside chance that you can use that script on Windows - I've just checked that an autoconfiscated package I created on Solaris was configurable on Windows under Cygwin and it mostly worked - all except some network handling. I'd not guarantee that it will always fail (but it's software - guaranteeing anything is pretty dangerous). I should add that the problem is in my auto-configuration code (the tests for the network functionality clearly aren't quite correct), and not in Cygwin per se. If I'd done the job properly, it would have worked. (Someone said "There is no portable code; there is only code that has been ported". That applies here.)
You do need a good simulation of a Unix environment. MingW might also work.
What do the preprocessor directives above it do?
Most likely, this is simply for determining some properties of your compiler, and it's greyed out because whatever the macro signifies, does not apply to your compiler.
Your problem is most likely elsewhere.
Since it can't find the function SDL_RWFromFP, you should probably see if that function is for some reason disabled by a preprocessor directive as well.
However, my guess is that the function exists, but does not get marked as __declspec( dllexport )
Without that, it won't get exposed so programs loading the DLL can call it. Most likely you have to #define something to specify that you want to create a DLL, which will enable the necessary preprocessor magic to insert the dllexport part in front of the function.
Normally, you should not have to add any HAVE_STDIO_H: those are not meant to be public anyway (although sadly many projects pollute the public namespace with those).
I would guess you did not build SDL correctly - or that Visual studio 2005 is not well supported by SDL (I don't know much about SDL, so those are really wild guesses without much information). Is there any test suite for SDL, such as you can test the built dll ?

Resources