如何从DLL导出C++类?

Apo*_*hay 19 c++ dll visual-c++

我有一个有两个重载函数的类.如何从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";
}
Run Code Online (Sandbox Code Playgroud)

Fre*_*abe 30

一种常见的方法是让一个宏(让它调用它EXPORT)扩展到dllimportdllexport取决于是否设置某种"立即构建DLL"定义,如下所示:

#ifdef MAKEDLL
#  define EXPORT __declspec(dllexport)
#else
#  define EXPORT __declspec(dllimport)
#endif

class EXPORT xyz {
  // ...
};
Run Code Online (Sandbox Code Playgroud)

我们的想法是,在构建DLL时,您需要添加MAKEDLL预处理器定义.这样,所有代码都将被导出.链接到您的DLL(因此包含此头文件)的客户端根本不需要执行任何操作.通过不定义MAKEDLL,它们将自动导入所有代码.

这种方法的优点是,正确获取宏的负担从许多(客户端)转移到DLL的作者.

这样做的缺点是,当按原样使用上面的代码时,不再可能直接将代码编译到某个客户端模块中,因为无法将EXPORT宏定义为空.要实现这一点,您需要进行另一项检查,如果为true,则将EXPORT定义为空.

在一个稍微不同的主题:在许多情况下,导出像这样的完整类是不可能的(或期望的!).相反,您可能只想导出所需的符号.例如,在您的情况下,您可能只想导出两个公共方法.这样,所有私有/受保护成员都不会被导出:

class xyz
{
public: 
    EXPORT void printing();
    EXPORT void printing(int a);
};
Run Code Online (Sandbox Code Playgroud)

  • 只记得Mehrdads的答案是正确的,因为导出的类只适用于这个特定的编译器版本和编译器设置.甚至不允许混合使用Debug和Release(例如,使用Release dll调试客户端). (4认同)

wee*_*ens 9

我记得,通常,您不是导出类而是导出一个工厂函数,它创建一个新的类实例并返回一个指针.类声明驻留在头文件中以便编译.

我可能错了这个例子(那是很久以前的事),但是在这里看起来应该是这样的:

头文件(.h):

class MyClass { ... };

extern "C" DLL_API MyClass* createMyClass();
Run Code Online (Sandbox Code Playgroud)

源文件(.cpp):

DLL_API MyClass* createMyClass() {
    return new MyClass();
}
Run Code Online (Sandbox Code Playgroud)

在编译时定义MY_DLL_EXPORT,请参阅foraidt的答案示例.

  • 这是实现它的最简单方法.但是不要忘记将工厂函数放在extern"C"{}语句中.C++的名称修改可能会阻止您从dll加载该函数. (3认同)

Sri*_*tha 8

另一种选择:

使用项目本地默认定义的宏。

您可以在以下位置查看项目本地默认定义的宏:

属性 -> C/C++ -> 预处理器 -> 预处理器定义。

例子:

假设您的项目名称是:MyDLL

该项目本地的默认宏: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 { 
             //.... 
  }
Run Code Online (Sandbox Code Playgroud)