1

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.

Bendrix
  • 98
  • 12
  • `dllimport` and `dllexport` are Windows-specfic DLL concepts. Linux does not use `.dll` binaries natively; Linux uses [shared object (`.so`)](https://stackoverflow.com/a/9688338/9516968) binaries. Are you trying to specifically load a `.dll` file in your Linux application? – Romen Jan 13 '20 at 14:51
  • Im not as familiar with linux based library loading, but yes the dllimport tries to load a dll, i obviously do not have one, so I was looking for a way to get around this dllimport call. I do already have a .so binary that I'm supposed to use, but Im not sure how to tell the .h files to use the .so instead of loading a dll with dllimport – Bendrix Jan 13 '20 at 14:57
  • @Romen How would I specifically link to a `.so` file. This is where im strugging, how exactly to link each header file to the `.so` – Bendrix Jan 13 '20 at 15:06
  • 1
    You would link a `.so` file the same way you would link a `.lib` or `.a` library. I think you may need to seek a C++ book or tutorial to ensure you have a good understanding of how the linker, libraries, and header files work together. All you need to do on linux is include the header for a library, and link to the `.so` for that library. There is no need for explicitly importing or exporting functions like you would with a Windows DLL; On linux a `.so` can be used just like a static library. – Romen Jan 13 '20 at 15:19
  • @Romen Thank you very much for your help. Ill give that a shot. – Bendrix Jan 13 '20 at 15:32
  • 1
    Also @Bendrix, I thought it might be helpful to point out that the `dllimport` you see in the code does not call a function or perform any *action*. It is an *attribute*, a description, for a function that tells the compiler/linker that the function exists in a DLL. The actual code for loading a DLL is something that the compiler inserts automatically as long as you link to the `.lib` file for that DLL. – Romen Jan 13 '20 at 16:04

1 Answers1

4

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);
Fire Lancer
  • 29,364
  • 31
  • 116
  • 182
  • When using MYLIB_EXPORT for example, so I just need to add the above to the header files, or do i need to change the source files to use whatever i call "MYLIB_EXPORT". And how do I specifically tell these header files to use the .so file I was given? – Bendrix Jan 13 '20 at 14:55
  • 1
    Can't be sure without seeing the headers, I would expect they already have a macro like that because of the need to switch between `dllexport` and `dllimport` and nothing for static library builds (rather than different physical copies of the headers), if so, just adding the "non-windows DLL" case to how it is defined will do (possibly just `#define UeiDaqAPI`). – Fire Lancer Jan 13 '20 at 15:23
  • Note: in Unix, dllexport is the default; dllimport is not necessary, as linker detects which symbols care from shared objects. (Also .lib files of Windows don't exist in Unix: they contain code that can be automagically generated linkage time -- actually gcc on Windows does just this: it can directly link from .dll files without .lib files.) – Lorinczy Zsigmond Jan 13 '20 at 19:43