C++ __declspec( dllexport ) functions cannot access instance variables - c++

I am trying to protect some C++ code by exporting as a DLL (on Windows/VS 2010).
In the example below var is set in the superclass constructor, and the debugger shows it is definitely set to reference something.
Test is constructed in the code that consumes the DLL the Test class is contained within.
But when go is called from on an instance of test (invoked from the DLL, but the invoking method is called by the DLL consumer) var is a null pointer (it's value is 0).
This is a simplification as I am not allowed to share the actual code.
//Headers
class Base {
public:
__declspec(dllexport) Base();
private:
Foo* var;
};
class Test : Base {
public:
__declspec(dllexport) Test();
__declspec(dllexport) void go();
private:
};
//Body
Base::Base() {
var = new Foo();
}
Test::Test() : Base() {
}
void Test::go() {
var->do_something();
}
In the consuming code, the header is
class Base {
public:
__declspec(dllimport) Base();
};
class Test {
public:
__declspec(dllimport) Test();
__declspec(dllimport) void go();
};
The actual code is much more complex, but I would be grateful if anyone can tell me whether there are known restrictions on instance variables with dllexport, or if it is more likely that I'm calling a method on a null pointer for Test, or perhaps it is a dllexport and inheritance problem. This code worked before I split the consumer code and DLL code was in the same project, it has only broken since splitting it up, dllexporting/dllimporting functions I want to expose into a second set of headers used by the consumer.

When you pass a Test by value from one place to another in the "consuming code", you'll cause slicing to occur because the client code is unaware of the variable and calculates an incorrect size for the class Test.
To solve this problem, you should declare the variable in the client code as well, or alternatively you can provide a static factory function of some kind and only allow the client code to pass pointers to Tests around to avoid slicing.

If you remove the instance variable from the code supplied to the customer, only your own code knows the real size of your object and can create it. From the top of my head you have two ways to go about this:
Supply a createTest static function that creates an instance of your class (factory method). The nicest thing to do here is to provide a pure interface (no instance variable).
If you only want to hide a specific part of your class you can use the pimpl idiom (wikipedia article).

Is there any reason to not use:
#ifdef IN_FOO_PROJECT
# define fooEXPORT __declspec(dllexport)
#else
# define fooEXPORT __declspec(dllimport)
#endif
class fooEXPORT exportClass
{
public:
void function( void );
Foo * var;
}
If you want to hide your class (or part of your class), you could use it as a private member:
#ifdef IN_FOO_PROJECT
# define fooEXPORT __declspec(dllexport)
#else
# define fooEXPORT __declspec(dllimport)
#endif
class classToHide;
class fooEXPORT exportClass
{
public:
void function( void );
classToHide * var;
}
And in Cpp:
#include "exportClass.h"
#include "classToHide.h"
void exportClass::function( void )
{
var->function();
}

Related

Way to use common class between C style exporting API in C++ DLL

I'm writing C++ library and now design C style API for it. For now I have bunch of methods that uses singleton of main class, here simplified declaration:
extern "C" {
MYDLL_API void getAudioDeviceList();
MYDLL_API void getWindowList();
MYDLL_API uint32_t BeginVideoCapture();
MYDLL_API uint32_t StopVideoCapture();
}
But so far I decided to remove singletons, there the dilemma. What is most elegant way to use my class through API calls? For now I see only one way, using global variable and init method, like (where CVideoConverter it's C struct wrap under C++ class):
extern "C" {
CVideoConverter* t = new CVideoConverter();
MYDLL_API void getAudioDeviceList();
MYDLL_API void getWindowList();
MYDLL_API uint32_t BeginVideoCapture();
MYDLL_API uint32_t StopVideoCapture();
}
Or should I create some C struct that will contain all API methods and pointer to CVideoConverter object, that export struct itself. Waiting for your suggestions, thanks!
Defining a global variable in a header file is never going to lead to happiness. Instead if you want a C API for your C++ code, I recommend you actually look at the FILE and standard C file handling functions.
The FILE type-alias is an opaque structure, you don't know its contents and neither should you care. Instead you have a function which allocates an instance of your opaque structure and returns a pointer to it. Then all your C API functions takes this pointer as an argument.
What this opaque structure really is? It doesn't really matter, it could simply be a private structure containing an instance of your main class. Then the C API functions which have the full definition of the structure and the classes) can use it to call the member functions needed.
A small and simple example:
The public header file, which is what the C applications should include:
#ifndef MY_C_API_H
#define MY_C_API_H
#ifdef __cplusplus
extern "C" {
#endif
// Forward declaration of the MYSTRUCT structure, and definition of type-alias
typedef struct MYSTRUCT MYSTRUCT;
MYSTRUCT *my_create(void);
void my_destroy(MYSTRUCT *mystruct);
void my_do_something(MYSTRUCT *mystruct, int some_argument);
#ifdef __cplusplus
}
#endif
#endif // End of header include guard
The private header file, to be used internally by your application only:
#ifndef MY_PRIVATE_H
#define MY_PRIVATE_H
#include "my_c_api.h"
#include "my_class.h"
struct MYSTRUCT
{
MyClass my_object;
};
#endif
The implementation of the C API:
#include "my_private.h"
extern "C"
{
MYSTRUCT *my_create(void)
{
return new MYSTRUCT;
}
void my_destroy(MYSTRUCT *mystruct)
{
delete mystruct;
}
void my_do_something(MYSTRUCT *mystruct, int some_argument)
{
mystruct->my_object.do_something(some_argument);
}
}
One good approach (not the only one), is to provide an instance factory function of your class CVideoConverter which will return a transtyped C instance via reinterpret_cast. This way, you can call your C exported function by providing this instance reference as 1st parameter. On DLL side, you retranstype into C++ instance and call your instance's method.
Please follow this link which provide more detailed explanations and very good examples.
C++ DLL to be used in C program

Defining a struct imported from DLL works only when its constructor is defined in the header file [duplicate]

This question already has answers here:
How do I safely pass objects, especially STL objects, to and from a DLL?
(4 answers)
Closed 7 years ago.
I have a class which has two overloaded functions. How do I export it from a dll and also how to use it by other C++ classes? My class looks like this:
#define DECLDIREXP __declspec(dllexport)
#define DECLDIRIMP __declspec(dllimport)
class DECLDIREXP xyz
{
public:
void printing();
void printing(int a);
};
using namespace std;
void xyz::printing()
{
cout<<"hello i donot take any argument";
}
void xyz::printing(int a)
{
cout<<"hello i take "<< a <<"as argument";
}
A common approach is to have a single macro (let's call it EXPORT) which either expands to dllimport or dllexport depending on whether some sort of "building the DLL right now" define is set, like this:
#ifdef MAKEDLL
# define EXPORT __declspec(dllexport)
#else
# define EXPORT __declspec(dllimport)
#endif
class EXPORT xyz {
// ...
};
The idea is that when building your DLL, you add MAKEDLL to the preprocessor definitions. That way, all the code will be exported. Clients who link against your DLL (and hence include this header file) don't need to do anything at all. By not defining MAKEDLL, they will automatically import all the code.
The advantage of this approach is that the burden of getting the macros right is moved from the many (the clients) to just the author of the DLL.
The disadvantage of this is that when using the code above as it is, it's no longer possible to just compile the code directly into some client module since it's not possible to define the EXPORT macro to nothing. To achieve that, you'd need to have another check which, if true, defines EXPORT to nothing.
On a slightly different topic: in many cases, it's not possible (or desired!) to export a complete class like that. Instead, you may want to just export the symbols you need. For instance, in your case, you may want to just export the two public methods. That way, all the private/protected members won't be exported:
class xyz
{
public:
EXPORT void printing();
EXPORT void printing(int a);
};
As I remember, normally, you export not a class but a factory function that creates a new instance of class and returns a pointer. The class declaration resides in header file for compile time.
I may be wrong about the example (that was long ago), but here how it should approximately look like:
Header file (.h):
class MyClass { ... };
extern "C" DLL_API MyClass* createMyClass();
Source file (.cpp):
DLL_API MyClass* createMyClass() {
return new MyClass();
}
Define MY_DLL_EXPORT while compiling, see foraidt's answer example.
One another option:
Use the default defined macro local to the project.
You can see the default defined macros local to the project in the below location:
Properties -> C/C++ -> Preprocessor -> Preprocessor Definition.
Example:
Suppose your Project Name is: MyDLL
Default Macro Local to that project: MYDLL_EXPORTS
#ifdef MYDLL_EXPORTS
/*Enabled as "export" while compiling the dll project*/
#define DLLEXPORT __declspec(dllexport)
#else
/*Enabled as "import" in the Client side for using already created dll file*/
#define DLLEXPORT __declspec(dllimport)
#endif
class DLLEXPORT Class_Name {
//....
}
When compiling your library you should define a macro (command line preprocessor definition), let's call it MY_DLL_EXPORT.
Then in your library's code do something like this:
#ifdef MY_DLL_EXPORT
# define DLL_API __declspec(dllexport)
#else
# define DLL_API __declspec(dllimport)
#endif
class DLL_API some_class { /*...*/ }

Why use macro in the class declaration

I am reading the source code of leveldb, esp. regarding mutexlock.
I found this declaration:
class SCOPED_LOCKABLE MutexLock {
public:
explicit MutexLock(port::Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu)
: mu_(mu) {
this->mu_->Lock();
}
~MutexLock() UNLOCK_FUNCTION() { this->mu_->Unlock(); }
private:
port::Mutex *const mu_;
// No copying allowed
MutexLock(const MutexLock&);
void operator=(const MutexLock&);
};
and I found that SCOPED_LOCKABLE is defined as empty, so why use it in the class declaration?
In class or function definitions if developer need to attach extra characteristic it uses MACROS than hard coding in each class or function definitions. This is a good practice for programming. because one day if you need to change this characteristic you have to change in only one place not everywhere of the code.
Some usage of macros in class definition
#ifdef CONTROLLER_EXPORTS
#define CONTROLLER_API __declspec(dllexport)
#else
#define CONTROLLER_API __declspec(dllimport)
#endif
class CONTROLLER_API CConfiguration{
} ;
You can get some more windows related useful clues here. http://msdn.microsoft.com/en-us/library/dabb5z75(v=vs.80).aspx
Even you can use access modifiers also like this, because some time for testing you may need to change the access level temporary.
#define PRIVATE private
#define PUBLIC public
class A{
PRIVATE:
int m_a;
PUBLIC:
int m_b;
}
Then what is exact your issue? it can be any useful characteristic define like above. here is one example i got from git
#define SCOPED_LOCKABLE __attribute__ ((scoped_lockable))
For details about __attribute__ check here
For the source I got above code check here
It might be defined as something different in a different environment. Sometimes it can affect linkage.
It can also indicate that other headers need to be included to make the library headers properly configured.

Creating Qt plugin and using non-virtual functions

First of all I use VS 2008 and dynamic build of Qt 4.7.0.
interface.h:
class PluginInterface
{
public:
virtual void foo() = 0;
};
Q_DECLARE_INTERFACE(PluginInterface, MY_PLUGIN_VERSION)
And I have and class which implements this interface:
myplugin.h
class MyPlugin: public QObject, public PluginInterface
{
public:
Q_OBJECT
Q_INTERFACES(PluginInterface)
virtual void foo(); // this functions is implemented in cpp file.
static QString goo(); // this function is also implemented in cpp file.
};
So when I use this plugin in other project(MySpecialPlugin) which will be compiled as dynamic-link library(actually also a plugin interface implementation) I can't call
MyPlugin::goo();
The header of "MyPlugin.h" is visible for MySpecialPlugin. And Ms VS2008 successfully compile the project. But I have error on link step LNK2001, undefined reference. But when change static void goo(); to virtual void goo(); it works.
I'm using Q_EXPORT_PLUGIN2 macro for creating plugins.
What I'm doing wrong? Does Qt set additional requirements on implementation of plugin interfaces?
First of all you need to export your class (on windows it's magic like __declspec(dllexport) after class keyword when compiling your "myplugin" and __declspec(dllimport) when compiling code using it (in this case MySpecialPlugin). You can achieve it with simple define. read more
#ifdef _WIN32
#ifdef MYPLUGIN_COMPILE
#define MYPLUGIN_EXPORT __declspec(dllexport)
#else
#define MYPLUGIN_EXPORT __declspec(dllimport)
#endif
#else
#define MYPLUGIN_EXPORT
#endif
class MYPLUGIN_EXPORT MyPlugin
{
// implementation
};
And add MYPLUGIN_COMPILE to preprocessor section of MyPlugin
You need to link against exporting library
Calling static and "normal" methods differs from calling virtual methods... static and "normal" methods are always at certain address and your code needs to know where is it... virtual call "checks" class vtable at what address your method has implementation and get that address "dynamicly" from that table. Additionaly win32 VC platform requires to define that something is "exported" (exposed) to access from outside of dll. So basicly if you want to call anything from MyPlugin directly (every member that is not virtual is called directly), you have to export it on win32 VC platform. Note that calling directly virtual method with MyPlugin::foo() will cause same error

How can I instantiate a class in a C++ dll, so that it maintains memory inbetween function calls?

I'm trying to write a dll that will store some values passed to it in between calls.
Currently, I have:
MyDll.h:
namespace MyDllNamespace
{
class MyClass
{
public:
static int getValue(int &a);
};
}
MyDll.cpp:
#include "ALERTDataAnalysisLibrary.h"
#include <stdexcept>
using namespace std;
namespace MyDllNamespace
{
int storedValue=0;
int MyClass::getValue(int &a)
{
a=a+storedValue;
}
}
MyDll.def
LIBRARY MyDllLibrary
EXPORTS
getValue #1
The idea is that the first time it is called, it returns the passed value, and the second time it's called it returns the sum of the passed value, and the previously passed value. (This is a bit cut down, the final version will have to work on arrays, and with more values, but one step at a time!)
I think what I want to do is stop getValue being static. Which would mean instantiating a class within the DLL (perhaps when it's loaded), and storing data in that. Then exposing a function of that class. I've no idea if that's the way to do it, I've not found anything like it after much searching.
You could export the whole class (and optionally use the pimpl idiom, but that's not mandatory):
In your DLL header file "MyDll.h", write the following:
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
class MYDLL_API MyClass
{
...
};
Then, make sure that MYDLL_EXPORTS is defined in your DLL project only, so when you compile your DLL, your class is "dllexported", while when included in your main application, it's "dllimported".
Also, you won't need the .def file anymore.