I've been working on compiling with Visual Studio 2015 a large number of code files written originally for use on linux, using g++. Specifically, I need a .dll for use with another program. Unfortunately, I have run into a number of problems.
After doing some research, I tried adding __declspec(dllexport) to the header files. This helped with some of the compilation errors, but didn't work for the static member functions and variables. I then made a .def file, which got rid of the remaining errors in compilation, but upon running some of the tests compiled at the same time (and with the same compiler), many of them failed due to segfaults. These same tests succeed if I build it as a .lib, or if I link the tests directly to various object files, but for the final program I need a .dll (The original build using g++ builds a .so). I have been unable to find anyone else with a problem similar to this.
Here is a simplified version of some of the code which I have found to be relevant to one of the lines which will cause a segfault:
In the library, the header:
class FirstClass
{
public:
static const char *FIRST_CLASS_NAME;
}
and the cpp file:
const char *FirstClass::FIRST_CLASS_NAME = "FIRST_CLASS";
Anything in the test file which references this variable will cause a segfault with a .dll. Specifically, if I have the line
std::cout << FirstClass::FIRST_CLASS_NAME << std::endl;
then if linked to a .dll it will segfault, but if linked to a .lib, it will output
FIRST_CLASS
As this is a project more to compile a large amount of code created by others (not all of which I understand, being rather new to c++), I would rather not have to do very much editing of the source code itself, but it seems like it should be more to do with
Any help in understanding what's going on here would be much appreciated.
The static data in the dll is in a different address space so you can't directly reference it (the call has to be mapped thru an import table). When you link a static library everything is in the address space of the executable so you can.
You must use dllexport and dllimport as a pair. dllexport where you define them in the shared library (dll) and dllimport where you use them in the application. You'll typically have a macro that evaluates to either __declspec(dllexport) or __declspec(dllimport) depending on where it's used. E.g.
And use it where you define the class:
Defining the symbol
_DLL
as appropriate in the respective projects. Visual Studio predefines_DLL
when you create a new dll project.There is no need for .def files in most cases these days.