Bendrix
Bendrix

Reputation: 118

Getting around __declspec(dllimport) in windows to linux project conversion

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

Answers (1)

Fire Lancer
Fire Lancer

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

Related Questions