Exporting constants from a DLL - c++

I'm working with VC9 on Windows.
I have a library (lets call it libfoo) which is made of the following files ("include guards" and "#include" directives omited for clarity's sake):
// foo.hpp
class Foo
{
public:
static const std::string SOME_CONST;
};
And:
// foo.cpp
#include "foo.hpp"
const std::string Foo::SOME_CONST = "hello";
Foo::SOME_CONST is exported using a .def file.
The library compiles fine: a libfoo.lib file and a libfoo.dll file are generated.
I used this library in a sample program, like:
// main.cpp
#include <foo.hpp>
int main()
{
std::cout << Foo::SOME_CONST << std::endl; // std::bad_alloc here
return EXIT_SUCCESS;
}
A std::bad_alloc is thrown whenever I attempt to use Foo::SOME_CONST.
This only happens if I link dynamically to libfoo. Linking statically results in a perfectly working program.
What could possibly be going on here ? Is it legal to export a std::string constant that way ?

Check if dll actually does dynamic initialization, because it might not, standard has no requirements for dynamic libraries. Wrapping globals in static functions can be the solution.

Use __declspec(dllexport) and __declspec(dllimport). Stop worrying about .def files and all of that rubbish- let the compiler do the work.

Are the library and the main application linking to the same version of the standard library and/or CRT and/or MFC, with exactly the same settings? I've seen allocation issues when using different versions of the CRT, and also fought bugs caused by different iterator debugging settings between a library and its including application.

Related

Static library able to link with any other object, regardless of C++ runtime used by that object

I am trying to determine if it is possible at all to create a static library that:
Internally uses Microsoft/STL, static release runtime (/MT)
Can be linked to objects not using /MT (e.g., Dynamic DLL Release, Static Debug, etc.)
The specific test code I'm trying to get working is as follows:
Header:
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
int EncapLibConcatenate(int a, int b);
#ifdef __cplusplus
}
#endif
Source:
#include "EncapLib.h"
#include <string>
int EncapLibConcatenate(int a, int b)
{
try {
return std::stoi(std::to_string(a) + std::to_string(b));
} catch (...) {
return 0;
}
}
Linking to the above predictably results in a /FAILIFMISMATCH error when not using /MT for the project that links to the above library. I would like to learn of any compiler / linker options to circumvent this issue. If such do not exist, then any other approaches (such as modifying the .obj COFF files post-build) would also be welcome.
As a side note, I am aware that creating a dynamic library is the idiomatic approach to encapsulating library dependencies; this is a question regarding technical possibilities, not best practices. I have also been able to create a runtime-agnostic static library by eschewing any use of the standard library (restricting to C runtime and win32). This question is specifically about a static library that uses the C++ standard library internally (though pointedly not at its interface).

C++ Library Cross-Calling

I'm not really sure if that is the actual name of what I mean, but you'll get it.
Supose I have 3 projects, 2 of them builds as libraries, and the other one as an executable. For my scenario I'll use MSVC++ and the libraries will be dynamic (DLLs), and of course executable .exe, but I also want to if static libraries are also included.
And please, if I'm wrong on any of my assumptions, please correct me.
In the first library project, FirstLib.h:
#pragma once
#include <SecondLib.h>
#ifdef DLLONE_BUILD
#define DLLONE_API __declspec(dllexport)
#else
#define DLLONE_API __declspec(dllimport)
#endif
int DLLONE_API MainOne();
int DLLONE_API InternalOne();
and FirstLib.cpp:
#include <FirstLib.h>
int MainOne() { return InternalTwo(); }
int InternalOne() { return 100; }
Similarly, in the first project, SecondLib.h:
#pragma once
#include <FirstLib.h>
#ifdef DLLTWO_BUILD
#define DLLTWO_API __declspec(dllexport)
#else
#define DLLTWO_API __declspec(dllimport)
#endif
int DLLTWO_API MainTwo();
int DLLTWO_API InternalTwo();
SecondLib.cpp:
#include <SecondLib.h>
int MainTwo() { return InternalOne(); }
int InternalTwo() { return 200; }
Finally, in the executable project, main.cpp:
#include <FirstLib.h>
#include <SecondLib.h>
int main() { return MainOne() + MainTwo(); }
So when compiling the two libraries, I obtain the two .dll files, and two .lib files. Each library must have the other library .lib to link.
Then, the executable must be linked with the two .lib, and when executed, .dll should be in a known path for the exe, be the same path or some PATH.
Now for the questions:
Is doing this a correct aproach, or should be avoided?
Exe needs the two dlls, but each dll needs the other dll. Does each dll loads the other one again, or uses the same loaded version from .exe?
If they were static libraries, would each library be loaded two times, or just one? Or none of them?
And if you have a good resource where I can find more about this, it will be really apreciated.
Thanks in advance!
UPDATE as why would I do this : Imagine creating an engine.
I have (just to be consistent with the previous scenario) a library called Kernel, and a library called System. Also a binary project.
Kernel has the code regarding program execution (main loop), handling, base clases and other high level things.
System has the code regarding HAL and low level code. OpenGL things, file IO things, etc.
Binary has the main function, and program specific implementation of the engine.
Why do I need that cross-linking:
Kernel in Binary: main() (Binary) calls Kernel.Initialize() (Kernel).
System in Binary: CreateActor()(Binary) calls System.OpenGl.MeshCreate() (System)
System in Kernel: Kernel.Initialize()(Kernel) Initializes the Kernel, but also the System by calling System.Initialize()(System).
Kernel in System: class System(System) inherits from class Object(Kernel)
I know i could avoid this circular dependency by, say, Initializing System from binary calling System.Initialize()after Kernel.Initialize().
But then, Kernel will depend on no one, System would depend on Kernel, and Binary on both Kernel and System.
So my question remains in this case too
Is removing the cross dependency but to have this scheme a better aproach?
Same as question two: Does Binary and System both depending on Kernel as well asBinary in System represents double code, double loading or a performance or size downgrade or some kind of undesirable effect?

UnsatisfiedLinkError about Static Member initialized in class in ndk r15

I encounter a problem about UnsatisfiedLinkError.
My code is :
class ClassA
{
public:
static const int MY_ENUM_1 = 0;
};
I use Android Studio build my code to .a.
And then I write .so for link the interface of my lib via JNI.
I build the project successfully. But it occur an error about this while run-time,
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZN12LaChenEngine14GraphicsSystem22VertexBufferAccessList12DYNAMIC_DRAWE
LaChenEngine is the namespace.
GraphicsSystem is the namespace in LaChenEngine.
VertexBufferAccessList is my class for declaring all enum.
DYNAMIC_DRAW is one of enum in class VertexBufferAccessList.
Is this problem about version in ndk?
By the way, I develop my library on Windows Platform.
One possible cause is that one project defines a extern "C" function, and the other assumes that it is a C++ function.
More info: https://stackoverflow.com/a/1041880/755804
Another guess: check if that function is there in your .so, and if not, find out where it is.
In general, how I would approach such linkage problem is: I would start with a hello-jni application, adding one feature at a time (another library, C++ functions, C++ functions in name spaces, etc.)
I test many version of ndk, it still happen again and angin.
So I decide to change the code like this :
//.h
class ClassA
{
public:
static const int MY_ENUM_1;
};
//.cpp
const int ClassA::MY_ENUM_1 = 0;
And then, it work.
Thanks for all helps.

Is it possible to compile boost::recursive_mutex statically in C++ Builder

boost::recursive_mutex and boost::lock_guard seem to use boost_thread-bcb-mt-1_39.dll in C++ Builder 2010. I see that there is also static version - boost_thread-bcb-mt-1_39.lib.
My code is something like this:
boost::recursive_mutex mylock;
//...
boost::lock_guard<boost::recursive_mutex> lock(mylock);
However, if I set compile option to Release and set Dynamic RTL option to False all I get is Mixing a dll boost library with a static runtime is a really bad idea.... Returning Dynamic RTL to True compiles but then it needs additional DLL's - cc32100mt.dll and boost_thread-bcb-mt-1_39.dll.
Is there a way to compile it statically in a single exe? After all, LIB file is provided, it should be possible. Is it a problem with this version of C++ Builder or Boost?
What I needed was to define in a header file:
#define BOOST_THREAD_USE_LIB
right before:
#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/locks.hpp>
After then it compiles without any issues.

[windows] back linking

There is shared class. Declarator is in shared header, implementation is in main program. Main program load DLL and exec some function from it, function create object of shared class.
Test code:
shared_header.h:
#include<stdio.h>
class sharedClass{
public:
sharedClass();
};
plugin.cpp -> libplugin.dll
#include"shared_header.h"
extern "C"
void loader(){
printf("Plugin is loaded!\n");
new sharedClass;
}
base.cpp -> base.exe
#include"shared_header.h"
sharedClass::sharedClass(){
printf("Shared class is loaded!\n");
}
int main(){
/*
some actions to load libplugin.dll and exec function loader
*/
return 0;}
So, I want see
Plugin is loaded!
Shared class is loaded!
And it works on Linux. But while I link libplugin.dll on Windows I have error "undefined refernce to sharedClass::sharedClass()". How I need link program and plugin to use this way?
PS. Mingw, stable version.
PPS. I'm so sorry for my terrible English.
Windows DLLs are non exactly the same thing as UNIX/Linux shared objects.
On Windows, DLLs must be fully linked and have all their references defined. Therefore, as your file plugin.cpp references the sharedClass constructor, the linker will require that this constructor is defined and available to create the DLL. It is not possible to provide it in the executable that loads the DLL.
On UNIX/Linux, shared objects behave differently. Their dependencies are solved when they are loaded by the executable. Therefore, the executable can provide some of the functions needed by the shared object.