On the .dll file
//SWC.h
#ifndef _SWC_
# define _SWC_
# define SWC_CALL __declspec(dllexport)
#else
# define SWC_CALL __declspec(dllimport)
#endif
namespace SWC
{
struct SWC_CALL Mouse
{
//interface
};
class SWC_CALL SWC_Base : public someClass1, public someClass2
{
static Mouse mouse;
};
//other classes goes here...
}
//SWC_Base.cpp
namespace SWC
{
Mouse SWC_Base::mouse; //needed, to compile
//other SWC_Base function definition
}
On .exe file
with the static struct Mouse mouse I defined on the SWC_Base I get linking errors
I solve my problem by redefining it again on this file
//main.cpp
#include "SWC.h"
#pragma comment (lib, "..\\SWC")
SWC::Mouse SWC::SWC_Base::mouse; //<- why do I need to redefine it again?
int main()
{
//...
return 0;
}
I already define the SWC_Base::mouse on its .cpp file, why do I need to redefine it again on the file who uses it? I know I can have this more problems as my .dll project is growing with static variables on it.
If your calling code will use __declspec (dllimport) this trouble will be gone :)
#ifdef EXPORTING_SWC
#define SWC_CALL __declspec(dllexport)
#else
#define SWC_CALL __declspec(dllimport)
#endif
You have added an anymous namespace { } around your definition (in case that you posted the real code) in the header file. Each anonymous namespace will translated to a compilation unit specific namespace by the compiler. Therefore you get always a new class in a new namespace.
To solve the problem you can either
move the declaration, the defination, and all use to one source file
use a named namespace
Related
I am new at creating DLL's and I am trying to get a class from my DLL.
But I keep getting errors that the class is unknown.
I am not use a header file.
I am trying to create a working app based on what is writen here: https://myprogrammingnotes.com/create-dll-qt.html
DLL file
#ifndef DLLCLASS_H
#define DLLCLASS_H
//#include "dllclass_global.h"
#if defined(DLLCLASS_LIBRARY)
# define DLLCLASSSHARED_EXPORT __declspec(dllexport)
#else
# define DLLCLASSSHARED_EXPORT __declspec(dllimport)
#endif
class DLLCLASSSHARED_EXPORT DllClass
{
public:
DllClass();
virtual ~DllClass();
virtual bool fun(char *);
};
extern "C" DLLCLASSSHARED_EXPORT DllClass * getDllClass();
typedef DllClass* (*GetDllClass)();
#endif // DLLCLASS_H
App file
QLibrary mylib("mydll.dll");
if (!mylib.load())
{
return;
}
GetDllClass getDllClass = (GetDllClass)mylib.resolve("getGetDllClass");
if(!GetDllClass)
{
return;
}
DllClass *dllclass = getDllClass();
dllclass->fun((char*)"hello");
Errors
Question
Why is the type unknown?
Is it not included when the DLL is loaded?
I am not use a header file.
You positively need definitions for the class (typically from a header file). There is no way the application can compile if it doesn't know what the class is.
There's ways to have a minimal class and hide details, but the class you're calling into must be known.
In visual studio I've set configuration type as .dll instead of .exe and because of that sometimes I need to use __declspec(dllexport) or __declspec(dllimport) . So I've created macros for them inside header file called "Core"
#pragma once
#ifdef B5_PLATFORM_WINDOWS
#ifdef B5_BUILD_DLL
#define B5_API __declspec(dllexport)
#else
#define B5_API __declspec(dllimport)
#endif // B5_BUILD_DLL
#else
#error Bos5 only supports Windows!
#endif // B5_PLATFORM_WINDOWS
I have a class "Application" inside of my namespace "Bos5" which uses BS_API
#pragma once
#include "Core.h"
namespace Bos5 {
class B5_API Application
{
public:
Application();
~Application();
void Run();
};
}
everything works fine inside this project but when I reference this to another project for some reason visual studio thinks B5_API is a class and "Application" isn't. therefore code below doesn't compile saying namespace Bos5 doesn't have struct or class called "Application"
#include <FinalBos5.h>
class Sandbox : public Bos5::Application
{
public:
Sandbox(){}
~Sandbox(){}
};
int main() {
}
I think this image can better explain what I'm saying
Okay I've fixed it. turns out problem was completely different thing. My preprocessor didn't save some of the definitions so in second project B5_API wasn't getting defined
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 { /*...*/ }
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 was following a tutorial on how to create a C++/Cli DLL, for some reason I get a warning for each function declaration, here's the whole code:
// KRecognizer.h
#pragma once
namespace KR
{
class __declspec(dllimport) KinectRecognizer
{
public:
KinectRecognizer();
~KinectRecognizer();
int Display();
};
}
_
// KRecognizer.cpp
#include "stdafx.h"
#include "KRecognizer.h"
using namespace System;
KR::KinectRecognizer::KinectRecognizer()
{
}
KR::KinectRecognizer::~KinectRecognizer()
{
}
int
KR::KinectRecognizer::Display()
{
Console::WriteLine(L"Writing a line");
return 100;
}
Here are the error outputs:
http://pastie.org/3678144
I'm compiling with the /clr flag.
The header declares DLL import, which means the definition of the class comes from a DLL. Since you are providing the definition, this gives the linkage error. You'll want to use __declspec(dllexport) instead when defining the DLL.
Since you'll want to use the same header file in the app that will use the DLL, the following idiom is often used:
#ifdef MYAPI_EXPORTS
# define MYAPI __declspec(dllexport)
#else
# define MYAPI __declspec(dllimport)
#endif
And then use:
class MYAPI KinectRecognizer
#define MYAPI_EXPORTS before including the header in the DLL, but do not define it in the application using the header to import the DLL.