Hi I'm little bit confused with dllexport.When I use __declspec( dllexport ) for example in class
#define DllExport __declspec( dllexport )
class DllExport C {
int i;
virtual int func( void ) { return 1; }
};
do I export class C to dll file or do I export C class from dll file?
When compiling the DLL you have to write __declspec(dllexport) as you did. This tells the compiler you want it to be exported. When using the DLL you want __declspec(dllimport) in your included files. The compiler then knows that this functions and classes are in a DLL-file and need to be imported. Because you don't want to change your header-files that much, you should define a macro e.g. BUILD_DLL.
#ifdef BUILD_DLL
#define DLL_PORTING __declspec(dllexport)
#else
#define DLL_PORTING __declspec(dllimport)
#endif
Now you write in example.h:
class DLL_PORTING example_class { … };
In your .exe file just include the header files you need and everything will work.
Related
I have a set of functions written in C that I need to be able to call from another project written in C++. The C code is essentially some functions that do some calculations on a large data set. I didn't write them - all I want to do is allow my C++ project to be able to call those functions. My solution was to create a DLL for the C code and link it to my C++ project.
In order to make the DLL, I structured myCproj.h (the header in the C project, not C++ project) like so:
#ifdef __cplusplus
extern "C" {
#endif
struct __declspec(dllexport) neededStruct {
int a;
//I need to be able to initialize this struct in my C++ project.
}
__declspec(dllexport) void neededFunc( struct neededStruct *input ) {}
//I need to be able to call this function from my C++ project and feed
//it my local instance of neededStruct.
#ifdef __cplusplus
}
#endif
The src file, myCproj.c, was not changed at all. The function definitions do not have __declspec(dllexport)in front of them, nor is extern "C" inserted anywhere. The code compiles without error and produces myCproj.dll and myCproj.lib.
I then tell my C++ project in VS where to find myCproj.lib and myCproj.h accordingly and copy the DLL over to the directory where my C++ executable lives. To use the DLL, I gave myCPPproj.cpp the following addition:
#define DLLImport __declspec(dllimport)
struct DLLImport neededStruct input;
input.a = 0;
extern "C" DLLImport void neededFunc( &input );
However, I get error EO335 'linkage specification is not allowed' on that last line. What am I doing wrong?
It is preferable to use the same header for both the library and using code.
As mentioned, it is usually done by a conditional define, like the following:
MyLibrary.h:
#if defined(MYLIBRARY_API)
#define MYLIBRARY_EXPORTS __declspec(dllexport)
#else
#define MYLIBRARY_EXPORTS __declspec(dllimport)
#endif
#if defined(__cplusplus)
extern "C" {
#endif
MYLIBRARY_API bool MyLibFunc();
#if defined(__cplusplus)
#endif
MyLibrary.c:
#include "MyLibrary.h"
void MyLibFunc()
{
....
}
App.cpp:
#include <MyLibrary.h>
int main()
{
MyLibFunc();
}
The symbol MYLIBRARY_API will be defined for the library project (usually as a /D on the compiler command line). And if you use visual studio that is pretty much exactly what you get when creating a dll project with exports.
Here is a reproducing example
// in a header from a dll
class Window{
public:
MSG _declspec(dllexport) *getMessage(); //compiles
MSG* _declspec(dllexport) getMessage(); //fails
}
Definitions are set in a .cpp file.
In the Application, I cant access the Member function, why ? I am access the function of course from a instance of Window like:
Window App;
func_with_parameters(param,App.getMessage(),0,0); // not found !
Ok, first off.
__declspec(dllexport) MSG* GetMessage();
Is the proper way the function definition should be.
Secondly, the __declspec(dllexport) will need to be __declspec(dllimport) in the header file of the project that consumes the dll or it will not import. That is usually handled via macros such as this.
#ifdef _WINDLL // Defined by Visual Studio when building a Dll
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
Third, it may be better to export at the class level instead of the function level e.g.
class __declspec(dllexport) Window
or with the macro
class DLL_API Window
To be clear:
I'm aware that the below example demonstrates a dll-dependancy, i.e. one library is not self-containe, but depends on another library to function.
Let's say I'm creating a runtime library, Utility.dll, which contains various useful functions of general nature.
I create a header file Utility.h to be included in other files which need to use Utility.dll.
The header file looks like
#ifndef _UTILITY_H
#define _UTILITY_H
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
DLL_EXPORT void foo();
DLL_EXPORT void foo2();
....
#endif
When I compile the source code file Utility.cpp into machine code (into Utility.dll) I make sure BUILD_DLL is defined so DLL_EXPORT gets replaced with __declspec(dllexport). This makes the functions be exported to the .dll file.
Whenever I include the header Utility.h and link with the import library (Utility.lib for MS VS, libUtility.a for g++) and do not define BUILD_DLL, the function declarations in Utility.h begin with __declspec(dllimport) instead, telling the compiler that the functions are imported from a .dll (so to speak).
Now, let's say I'm also building another library, MyLibrary.dll, which wants to use some of the useful functions in Utility.dll. Similarily, I would create MyLibrary.h as
#ifndef _MYLIBRARY_H
#define _MYLIBRARY_H
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
DLL_EXPORT void myLibraryFunc1();
....
#endif
When I compile MyLibrary.cpp into MyLibrary.dll I'm including Utility.h and also linking against the Utility import library.
This leads us to my question:
Since I define BUILD_DLL also when I compile MyLibrary.dll, this means that the function declarations in Utility.h also will read
__declspec(dllexport) void foo();
__declspec(dllexport) void foo2();
....
Not
__declspec(dllimport) void foo();
__declspec(dllimport) void foo2();
Don't we want it to be __declspec(dllimport) for the function declarations in Utility.h when we compile MyLibrary.dll, and __declspec(dllexport) for the function declarations in MyLibrary.h?
This is precisely the reason why you normally don't name such macros BUILD_DLL, but BUILD_UTILITY and BUILD_MYLIBRARY or similar. Likewise, the declspec macro should not be DLL_EXPORT, but UTILITY_EXPORT and MYLIBRARY_EXPORT (or perhaps UTILITY_API and MYLIBRARY_API).
I have a base class (QIndicator) and I want to implement derived classes in DLLs. The DLL project in Visual Studio 2012 for a sample derived class has the following code:
header file with base class
#ifndef _DLL_COMMON_INDICATOR_
#define _DLL_COMMON_INDICATOR_
// define the DLL storage specifier macro
#if defined DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif
class QIndicator
{
private:
int x;
int y;
};
extern "C"
{
// declare the factory function for exporting a pointer to QIndicator
DECLDIR QIndicator * __stdcall getIndicatorPtr(void);
}
#endif
source file with derived class
#define DLL_EXPORT
#include "indicator.h"
class QIndicatorDer : public QIndicator
{
public:
QIndicatorDer (void) : QIndicator(){};
~QIndicatorDer (void){};
private:
// list of QIndicatorDer parameters
int x2;
int y2;
};
extern "C"
{
DECLDIR QIndicator * __stdcall getIndicatorPtr(void)
{
return new QIndicatorDer();
};
}
The problem I have is that upon successful build, the produced DLL file does not contain the exported getIndicatorPtr function (as shown by DependencyWalker). I checked whether the dllexport keyword gets propagated properly into the declaration of getIndicatorPtr and it does.
Another interesting problem is that I already have another derived class like this, in another DLL project, that I created some months ago. This older project is basically the same and everything works well there. I checked all properties of both the old and the current projects, and they seem identical. So I ran out of ideas, why I can't get getIndicatorPtr to export.
Any help is much appreciated,
Daniel
That's because it's not being exported. Why?
__declspec specifier should only be placed in the declaration of a function, not it's definition. Also, avoid something like #define DLL_EXPORT. Preprocessor definitions should either defined in project properties (MSVC) or command line option (-D in GCC, for example).
Look at you code:
Header
extern "C"
{
DECLDIR QIndicator * __stdcall getIndicatorPtr(void);
}
When compiler parses this header, is sees DECLDIR as dllimport (because you define DLL_EXPORT in .cpp). Then in .cpp, it suddenly appears as dllexport. Which one is used? The first one.
So, leave your header (it's fine), but change your source:
//#define DLL_EXPORT -> remove this!
#include "indicator.h"
class QIndicatorDer : public QIndicator
{
//...
};
extern "C"
{
/* DECLDIR -> and this! */ QIndicator * __stdcall getIndicatorPtr(void)
{
return new QIndicatorDer();
};
}
Then, go to project properties (I assume you use Visual Studio) and then C/C++ -> Preprocessor -> Preprocessor Definitions and add there DLL_EXPORT=1.
That should work.
I'm building a C++ DLL for one of my projects. I am trying to standardize the way that are class are defined. So instead of each time writing:
class __declspec(dllexport) ClassName
I'm building a #define macro to ease this process:
#define CLASS( cName ) class __declspec(dllexport) cName
But, when I'm using it, it gives me the following error:
Error: Expected a ';'
I know you can use a #define macro to define an entire class creation, but can it be used to define only the "class header" ?
Thanks,
Keep in mind that I'm trying to do so because we are going to deal with hundreds of classes, so these kinds of "automation" would be most helpful :)
EDIT:
example:
#define CLASS( nClass ) class __declspec(dllexport) nClass
CLASS( APTest )
{ // Here is the error of missing ';'
public:
APTest();
};
Don't do this.
C++ has already been standardized!
If you ever expect other people to read your code then just write it in conventional C++, not some homecooked dialect that looks different. Get used to the proper C++ syntax, it will make it easier to read other people's C++ code.
One thing that does make sense is to simplify the __declspec part, which you can do like this:
#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif
class DLLEXPORT APTest
{
// ...
};
You're really not making your life any simpler by writing CLASS( APTest ) and you make it harder for others to understand. Just say no.
There is a better way than #Wakely. Do it like this:
#ifdef MYLIB_DLL
#ifndef MYLIB_IFACE
#ifdef MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllexport )
#else // !MYLIB_IFACE_EXPORT
#define MYLIB_IFACE _declspec( dllimport )
#endif // !MYLIB_IFACE_EXPORT
#endif // !MYLIB_IFACE
#else // !MYLIB_DLL
#ifndef MYLIB_IFACE
#define MYLIB_IFACE
#endif // !MYLIB_IFACE
Put a block like that in a header that is used by every file in your dll, and in the public header for your dll.
Every symbol that should be exported from your dll gets tagged like this:
class MYLIB_IFACE MyClass
{
};
void MYLIB_IFACE myFunc();
Then in every .cpp file in your dll the first line should be:
#define MYLIB_IFACE_EXPORT
If you do this, then it will build just fine on POSIX systems that don't use dllexport/dllimport. To build a dll version of your lib you define MYLIB_DLL. ( you can do this in the compiler's flags so it can be controlled from your build system )
To build a static version of your lib, don't define MYLIB_DLL.
#Update:
You can extend this to support GCC visilibity like this:
#ifdef WIN32
#define KX_SYMBOL_EXPORT _declspec( dllexport )
#define KX_SYMBOL_IMPORT _declspec( dllimport )
#else // GCC
#define KX_SYMBOL_EXPORT __attribute__(( visibility ("default")))
#define KX_SYMBOL_IMPORT
#endif
#ifdef KX_DLL
#ifndef KX_IFACE
#ifdef KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_EXPORT
#else // !KX_IFACE_EXPORT
#define KX_IFACE KX_SYMBOL_IMPORT
#endif // !KX_IFACE_EXPORT
#endif // !KX_IFACE
#else // !KX_DLL
#ifndef KX_IFACE
#define KX_IFACE
#endif // !KX_IFACE
#endif // !KX_DLL
I remove the GCC bit in the first example for simplicity. But this is how a really do it. #Wakely is so right.