我有一个有两个重载函数的类。如何从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";
}
答案 0 :(得分:28)
一种常见的方法是使用一个宏(我们称之为EXPORT
),它可以扩展为dllimport
或dllexport
,具体取决于是否某种“立即构建DLL” define设置,如下所示:
#ifdef MAKEDLL
# define EXPORT __declspec(dllexport)
#else
# define EXPORT __declspec(dllimport)
#endif
class EXPORT xyz {
// ...
};
这个想法是在构建DLL时,将MAKEDLL
添加到预处理器定义中。这样,所有代码都将被导出。链接到您的DLL(因此包含此头文件)的客户端根本不需要执行任何操作。通过不定义MAKEDLL
,他们将自动导入所有代码。
这种方法的优点是,正确获取宏的负担从许多(客户端)转移到DLL的作者。
这样做的缺点是,当按原样使用上面的代码时,不再可能直接将代码编译到某个客户端模块中,因为无法将EXPORT
宏定义为空。要实现这一点,您需要另外检查,如果为true,则将EXPORT定义为无。
在一个稍微不同的主题上:在许多情况下,导出像这样的完整类是不可能的(或期望的!)。相反,您可能只想导出所需的符号。例如,在您的情况下,您可能只想导出两个公共方法。这样,所有私人/受保护成员都不会被导出:
class xyz
{
public:
EXPORT void printing();
EXPORT void printing(int a);
};
答案 1 :(得分:9)
我记得,通常,您不是导出类,而是导出一个创建类的新实例并返回指针的工厂函数。类声明驻留在头文件中以便编译。
我可能错了这个例子(那是很久以前的事),但在这里它应该是如何看起来像:
头文件(.h):
class MyClass { ... };
extern "C" DLL_API MyClass* createMyClass();
源文件(.cpp):
DLL_API MyClass* createMyClass() {
return new MyClass();
}
编译时定义MY_DLL_EXPORT,请参阅foraidt的答案示例。
答案 2 :(得分:3)
另一个选择:
将默认定义的宏本地用于项目。
您可以在以下位置查看项目本地的默认定义宏:
属性 - &gt; C / C ++ - &gt;预处理器 - &gt;预处理器定义。
示例:强>
假设您的项目名称为: 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 {
//....
}
答案 3 :(得分:1)
编译库时,您应该定义一个宏(命令行预处理器定义),让我们称之为MY_DLL_EXPORT
。
然后在您的图书馆代码中执行以下操作:
#ifdef MY_DLL_EXPORT
# define DLL_API __declspec(dllexport)
#else
# define DLL_API __declspec(dllimport)
#endif
class DLL_API some_class { /*...*/ }