如何从 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:45:17  来源:igfitidea点击:

How to export a C++ class from a dll?

c++visual-c++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 dllimportor dllexportdepending on whether some sort of "building the DLL right now" define is set, like this:

一种常见的方法是使用单个宏(我们称之为EXPORT),它可以扩展为dllimportdllexport取决于是否设置了某种“立即构建 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 MAKEDLLto 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 EXPORTmacro 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 { /*...*/ }