如何从 dll 导出 C++ 类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6840576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to export a C++ class from a dll?
提问by Apoorva sahay
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:
我有一个有两个重载函数的类。如何从 dll 中导出它以及如何通过其他 C++ 类使用它?我的课是这样的:
#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";
}
回答by Frerich Raabe
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:
一种常见的方法是使用单个宏(我们称之为EXPORT
),它可以扩展为dllimport
或dllexport
取决于是否设置了某种“立即构建 DLL”定义,如下所示:
#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.
这个想法是在构建 DLL 时,添加MAKEDLL
到预处理器定义中。这样,所有代码都将被导出。链接到您的 DLL(并因此包含此头文件)的客户端根本不需要做任何事情。通过不定义MAKEDLL
,它们将自动导入所有代码。
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.
这种方法的优点是使宏正确的负担从许多(客户端)转移到 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.
这样做的缺点是,当按原样使用上面的代码时,不再可能直接将代码编译到某个客户端模块中,因为不可能将EXPORT
宏定义为空。要实现这一点,您需要进行另一项检查,如果为真,则将 EXPORT 定义为空。
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);
};
回答by weekens
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):
头文件 (.h):
class MyClass { ... };
extern "C" DLL_API MyClass* createMyClass();
Source file (.cpp):
源文件 (.cpp):
DLL_API MyClass* createMyClass() {
return new MyClass();
}
Define MY_DLL_EXPORT while compiling, see foraidt's answer example.
编译时定义 MY_DLL_EXPORT,参见 foraidt 的回答示例。
回答by SridharKritha
One another option:
另一种选择:
Use the defaultdefined macro localto the project.
使用项目本地的默认定义宏。
You can see the default defined macros local to the project in the below location:
您可以在以下位置看到项目本地默认定义的宏:
Properties -> C/C++ -> Preprocessor -> Preprocessor Definition.
属性 -> C/C++ -> 预处理器 -> 预处理器定义。
Example:
例子:
Suppose your Project Name is: MyDLL
假设您的项目名称是:MyDLL
Default Macro Local to that project: MYDLL_EXPORTS
该项目的默认宏本地: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 {
//....
}
回答by foraidt
When compiling your library you should define a macro (command line preprocessor definition), let's call it MY_DLL_EXPORT
.
在编译你的库时,你应该定义一个宏(命令行预处理器定义),我们称之为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 { /*...*/ }