Reputation: 118
Im in the process of converting a visual studio c++ framework over into a linux build, and in the process of eliminating windows dependencies I ran into a whole bunch of __declspec(dllimport) calls in some header files. These header files define a bunch of functions and classes that are used in the source files, so theyre needed for the build.
Heres the exact lines that use the __declspec() call.
#ifndef UeiDaqAPI
#define UeiDaqAPI __declspec(dllimport)
#endif
UeiDaqAPI is the collection of classes and functions that all the source files use. The declspec call, from what I understand, links the functions/classes defined in the current .h file to the dynamic library "UeiDaqAPI"
__declspec(dllimport) is not supported by linux, so ive tried a "workaround" using dlopen(). For some more background information, about 40 header files use the above __declspec() call, so testing any workaround is very tedious. I was given a dynamic library for linux, in the .so format that I'm supposed to use.
I found an example of using dlopen(path-to-library) that should allow me to get around the __declspec() call but I am unsure how to get it working correctly. So far I have tried following the example, and changed all 40 or so header files and replaced the __declspec() call with the following:
#ifndef UeiDaqAPI
string nameOfLibToLoad("path/to/lib/lib.so");
UeiDaqAPI = dlopen(nameOfLibToLoad.c_str(), RTLD_LAZY);
if (!lib_handle) {
cerr << "Cannot load library: " << dlerror() << endl;
}
#endif
This however, I get errors stating that function calls that ARE defined in the header files were not defined, I suspect this is because they dont get added to the .so library, but Im not sure.
Id like some help either with implementing the above workaround, or, if there is a better way to get around the __declspec() call, then id like some pointers on where to start.
Upvotes: 1
Views: 2650
Reputation: 30105
You shouldn't need to use dlopen
, that is for dynamic loading (LoadLibrary
/dlopen
, GetProcAddress
/dlsym
, FreeLibrary
/dlclose
).
Instead as with Windows in the basic case it should be automatic, but the syntax is a little different.
Windows/MSVC generally only exports things from DLL's that it was specifically told to by __declspec(dllexport)
and then when using the DLL only tries to link things explicitly told to by __declspec(dllimport)
.
GCC/Linux however by default (you can opt-in to an explicit export style) just exports everything in a .so
, and when linking considers any object or library, so just declaring the function is enough, like for a static library or multiple C/C++ files.
void my_uei_daq_api_function(int a, int b);
Often in portable libraries there might be something along the lines of:
#if defined(_WIN32) && defined(MYLIB_DLL)
# ifdef MYLIB_BUILD
// Compiling a Windows DLL
# define MYLIB_EXPORT __declspec(dllexport)
# else
// Using a Windows DLL
# define MYLIB_EXPORT __declspec(dllimport)
# endif
// Windows or Linux static library, or Linux so
#else
# define MYLIB_EXPORT
#endif
Which is then used in the libraries headers:
MYLIB_EXPORT void my_uei_daq_api_function(int a, int b);
Upvotes: 6