I am currently building a program using GLEW, compiled with MinGW ( in Eclipse ). I built the GLEW libs from the source provided by the GLEW website.
I have been able to use the GLEW declared functions without a problem if I link with the .DLL. However, if I try to link with the static library ( libglew32.a ) with the "GLEW_STATIC" flag defined, I get an error for the function "glewInit()":
undefined reference to `imp_glewInit#0'
If I open up libglew32.a in a hex editor, I can see that there is an entry, but it is named _glewInit#0. So it seems like the disconnect is that my program's compile is trying to append this "imp" string to the front of the function name in the library.
It seems like there must be mis-match of the calling convention here, but I don't know what would cause it yet. There are certainly lots of different ways that GLEW declares the api functions in the header depending on what compiler definitions are set, but I haven't narrowed it down yet.
Any ideas out there?
It looks like that imp prefix gets added for function stubs that are intended to be loaded at runtime from a .DLL. In other words, I wasn't actually staticly linking against GLEW. It turned out that I didn't quite have my eclipse C++ symbols set up correctly, so GLEW_STATIC was not being defined. After making sure that it was set up in the g++ call, it links just fine.
Related
I have a legacy Windows project using the legacy 32 Bit C++ compiler. For various reasons I need to use the Windows 8+ function PathCchCanonicalizeEx. C++Builder seems to provide the header and some module definition file for that, but I can't find any library to link against:
[ilink32 Error] Error: Unresolved external 'PathCchCanonicalizeEx' referenced from C:\[...]\WIN32\DEBUG\TMP\FILE.OBJ
How am I supposed to fix this? Do I need to add a Windows 8.1 SDK? Is the necessary lib simply named differently and I can't find it? Something completely different?
According my tests, one has two options:
IMPLIB/MKEXP
I'm developing/testing a some Windows 10 21H2, which provides an implementation for PathCchCanonicalizeEx in some DLL already. So if that source DLL is known, one can use IMPLIB or MKEXP to create an import library manually. I did that and after adding the created library from IMPLIB to my project, the linker errors were instantly gone.
Though, it's not that easy to know where PathCchCanonicalizeEx is placed in. One pretty easily finds the api-ms-win-core-path-l1-1-0.dll, but that thing is NOT an actual file on the disk and therefore can't be used by IMPLIB or MKEXP. That name is only a virtual concept for the library loader to address the same named API set of modern Windows, the extension .dll doesn't mean it's a file at all.
You can use an API set name in the context of a loader operation such as LoadLibrary or P/Invoke instead of a DLL module name to ensure a correct route to the implementation no matter where the API is actually implemented on the current device. However, when you do this you must append the string .dll at the end of the contract name. This is a requirement of the loader to function properly, and is not considered actually a part of the contract name. Although contract names appear similar to DLL names in this context, they are fundamentally different from DLL module names and do not directly refer to a file on disk.
https://learn.microsoft.com/en-us/windows/win32/apiindex/windows-apisets#api-set-contract-names
What you really need to work with is KernelBase.dll, which is even documented by MS.
implib "KernelBase x86.lib" C:\Windows\SysWOW64\KernelBase.dll
implib "KernelBase x86-64.lib" C:\Windows\System32\KernelBase.dll
Module Definition File
The downside of manually creating LIB files is that one needs to maintain those with the project. Things depend on if the target is 32 or 64 Bit, DEBUG or RELEASE, so paths might become a bit complex, one might need to create relative paths for libraries in the project settings using placeholders for the target and stuff like that.
It seems that all of this can be avoided with Module Definition Files, which's purpose is to provide IMPORT and EXPORT statements to either consume exported functions by other DLLs or make that possible for others with own functions. I've successfully resolved my linker problems by simply creating a file named like my app using the extension .def alongside my other project files. That file needs to be added to the project, though.
dbxml.cbproj
dbxml.cbproj.local
dbxml.cpp
dbxml.def
dbxml.res
[...]
The following content made the app use the correct function from the correct DLL. Though, what didn't work was using the API set name, which resulted in an error message by the linker.
IMPORTS
KernelBase.PathCchCanonicalizeEx
IMPORTS
api-ms-win-core-path-l1-1-0.PathCchCanonicalizeEx
[ilink32 Error] Invalid command line switch for "ilink32". Parameter "ItemSpec" cannot be null.
[ilink32 Error] Fatal: Error processing .DEF file
The latter is after restarting C++Builder, so I guess the format of the file is simply wrong because of the API set name.
I did quite a bit of googling for a definitive answer, but I could not find one.
We have cross-platform sources that need to be used by our iOS apps. I have already packaged them as static framework and got a test app to link successfully against and make a call into it.
The problem I am having is that it makes heavy use of global static constructors.
I am seeing erratic behavior with only a subset of objects getting instantiated but not all.
My questions:
Do static constructors even work within the context of an iOS static
lib?
How would one debug such a problem?
Thanks!
constructors in a static library get called erratically
The use of -all_load and -force_load does not make any difference in invocation of constructor attribute labeled functions
What you need to do is this:
make sure the constructors are global symbols. do this by exporting them via a symbols' file.
consider creating an init function and use the linker setting "initialization routine" to control the order of the instantiation of your global objects..
Do static constructors work within the context of an iOS static lib?
They only start to work once they're linked into an executable, but once that is accomplished they will work.
How do you debug such a problem
There are a few approaches
You have to presume no specific order of the invocation of the constructors.
Make sure the constructors are being linked into the executable (use nm to determine this)
You can try an -Wl,-all_load to get it to load all the components of all archives into the executable (or -Wl,-force_load,libstatic.a to just load for a specific static archive).
I've tried to formulate the problem in an abstract way, but anyway I give details about the actual libraries in the end.
Dynamic library Addon is statically linked against other library WebRTC which has some code in assembly and this code is linked into WebRTC as object files together with WebRTC's own object files. Lets call this assembly code VP8. Functions of VP8 are marked extern inside WebRTC. Some function Encode() from Addon calls functions of WebRTC which eventually calls functions from VP8.
Now, the application Firefox which is going to load library Addon is quite complex and has its own version (means statically linked) of library WebRTC(let's call it WebRTC2), but an older one.
So, here is a problem: if a call of Encode() is made from the application Firefox, WebRTC functions get called (not WebRTC2, which is correct) BUT when WebRTC tries to call VP8 functions, they get called from the WebRTC2 version (means application's version of WebRTC), but not from WebRTC.
Is there are way to force WebRTC make calls only from local copy of VP8?
Application Firefox is a Firefox browser, WebRTC is a WebRTC library, VP8 is a VP8 codec library (inside WebRTC) and Addon is my Firefox C++ add-on.
UPDATE - DETAILED DESCRIPTION
Here is "unabstract" description of the problem:
So there is a C++ XPCOM add-on which is statically linked against latest version of WebRTC library.
At some point inside add-on a call for encoding a frame is made (method Encode of VP8Encoder class) and it crashes in Firefox all the time, while continue to work well on test programs using gtest framework.
The problem is that at some point inside WebRTC there is VP8 assembly code which is get called for encoding and functions of this assembly code are declared as extern in implementation files. Actually, it crashes on vp8_intra_pred_y_ve_sse2 function.
I've compared three assembly codes of this function: one is from my version of WebRTC (used in add-on), second - where debugger crashed and the third one - from source code of Mozilla's WebRTC.
It turned out that for some weird reason, Mozilla's code get called instead of add-on's WebRTC (they both have same names of course) and as Mozilla's WebRTC code is outdated, it crashes with EXC_BAD_ACCESS.
This probably won't be much help to you, but since no one else has responded, here I go ...
You didn't mention if you're running on Linux, Windows, or something else. My answer is for Linux. I believe Windows loads dynamic libraries differently.
I think what's happening is that you've statically linked against the WebRTC library stub interfaces and those stub interfaces are dynamically linking to the actual implementation, and then getting the first instance of the WebRTC library loaded into firefox instead of the second. Be sure that you're really linking against a statically compiled version of the WebRTC library.
The linux dlopen(3) man page has an interesting flag listed that seems like it would help if your library was the one loading the WebRTC library:
void *dlopen(const char *filename, int flag);
dlopen()
The function dlopen() loads the dynamic library file named by the null-
terminated string filename and returns an opaque "handle" for the
dynamic library. [...]
RTLD_DEEPBIND (since glibc 2.3.4)
Place the lookup scope of the symbols in this library ahead of
the global scope. This means that a self-contained library will
use its own symbols in preference to global symbols with the
same name contained in libraries that have already been loaded.
This flag is not specified in POSIX.1-2001.
Unfortunately, firefox is the one loading your library.
If your library was dynamically linked against WebRTC (which it seems to be) and you explicitly loaded the WebRTC library you want using dl_open() with the RTLD_DEEPBIND flag, than that would solve your problem.
This won't help you much since its not your code that's binding to vp8_intra_pred_y_ve_sse2, but its worth pointing out that gcc also has the dlsym() function which can take a couple of special flags:
void *dlsym(void *handle, const char *symbol);
dlsym()
The function dlsym() takes a "handle" of a dynamic library returned by
dlopen() and the null-terminated symbol name, returning the address
where that symbol is loaded into memory. [...]
There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The
former will find the first occurrence of the desired symbol using the
default library search order. The latter will find the next occurrence
of a function in the search order after the current library. This
allows one to provide a wrapper around a function in another shared
library.
You could use that in your code to at least debug what's going on by having it print out the values it gets for a lookup of vp8_intra_pred_y_ve_sse2.
Finally, the same man page notes that linux has a dlvsm() that takes a version string argument as well, allowing the XPCOM code to specify which version of the function it wants:
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <dlfcn.h>
void *dlvsym(void *handle, char *symbol, char *version);
If it were me, and I was forced to dynamically link the stuff, I'd go with the brute force approach. Go into the libraries and change the function names (in both libraries). Its not elegant, and it will be a headache whenever a new version of either library comes out, but its simple and direct.
I am working on an iOS app which links several static libraries. The challenge is, those linked libraries define same method names with different implementations. Oddly, I don't get any duplicate symbol definition errors; but, to no surprise, I end up with access to only one implementation of the method.
To be more clear, say I have libA and libB and they both define a global C method called func1()
When I link both libA and libB, and make a call to func1(), it resolves to either libA's or libB's implementation without any compilation warning. I, however, need to be able to access both libA's func1() and libB's func1() separately.
There's a similar SO post that explains how it can be done in C (via symbol renaming) but unfortunately, as I found out, objcopy tool doesn't work for ARM architecture (hence iPhone).
(I will submit it to the App Store, hence, dynamic linking is not an option)
It appears that you are in luck - you can still rename symbols with the ARM binary format, it's just a bit more hacky than the objcopy method...
NOTE: This has only been tested minimally, and I would strongly advise you to make a backup of all libraries in question before trying this!
Also note that this only works for files not compiled with the C++ compiler! This will fail if the C++ compiler was used on these files.
First, you will need a decent hex editor, for this example, I will be using Hex Fiend.
Next, you will open up a copy of your of of your libraries, let's call it lib1-renamed.a, and do the following with it:
Find the name of the symbol you wish to re-name. It can be found using the nm tool, or, if you know the header name, you should be set.
Next, you will use hex fiend, and to a textual replace of the old name (in this case foo), and give it a new name (in this case, bar). These names must have the same length, or it will corrupt the binary's offsets!
Note: if there is more than one function that contain's foo's name in it, you may have problems.
Now, you must edit the headers of the library you changed, to use the new function name (bar) instead of the old one.
If you have done the three simple† steps above properly, you should now be able to compile & link the two files successfully, and call both implementations.
If you are trying to do this with a universal binary (e.g. one the works on the simulator as well), you'd be best off using lipo to separate the two binaries, using objcopy on the i386/x64 binary, and then using my method on the ARM binary, and lipo it back together.
†: Simplicity is not guaranteed, nor is it covered by the Richard J. Ross III super warranty. For more information about the super warranty, call 1-800-FREE-WARRANTY now. That's 1-800-FREE-WARRANTY now!
I have embedded Lua on Win32 in my project by means of statically linking it in (no, I can't switch to DLL). I would like to bundle more Lua extensions that use native code - not just pure .lua files. Specifically, I want to bundle Steve Donovan's winapi which comes as some lua files and some .c files.
How to do it?
You need to do two things. First, you have to compile the Lua DLL projects into non-DLL projects. Since they're intended to be DLL modules, they probably won't have provisions for this in their build systems. That means you have to do it yourself. Get rid of the DLL main functions and other specialized DLL functions (but take note of what they do and make sure you replicate it if it's important). And make sure that you change any #defines that try to include Lua with dynamic linking.
All Lua module DLLs export one or more functions of the form luaopen_*, where * is the name of the module to load. This function will likely be decorated with declspec() notation. Typically, the notation is done via a preprocessor macro, but it may not be. Either way, remove it, turning it into a normal function declaration.
Now, once you have created your lua_State object, just call that luaopen_* function with your lua_State.