提问人:Apoorva sahay 提问时间:7/27/2011 最后编辑:Bo PerssonApoorva sahay 更新时间:6/13/2014 访问量:89815
如何从 dll 导出 C++ 类?[复制]
How to export a C++ class from a dll? [duplicate]
问:
我有一个类,它有两个重载函数。如何从 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";
}
答:
一种常见的方法是使用单个宏(我们称之为宏),该宏可以扩展为或取决于是否设置了某种“立即构建DLL”定义,如下所示:EXPORT
dllimport
dllexport
#ifdef MAKEDLL
# define EXPORT __declspec(dllexport)
#else
# define EXPORT __declspec(dllimport)
#endif
class EXPORT xyz {
// ...
};
这个想法是,在生成 DLL 时,将添加到预处理器定义中。这样,所有代码都将被导出。链接到 DLL(因此包含此头文件)的客户端根本不需要执行任何操作。通过不定义,它们将自动导入所有代码。MAKEDLL
MAKEDLL
这种方法的优点是,正确获取宏的负担从许多(客户端)转移到 DLL 的作者身上。
这样做的缺点是,当按原样使用上述代码时,不再可能将代码直接编译到某个客户端模块中,因为不可能将宏定义为无。为了实现这一点,你需要有另一个检查,如果为真,则将 EXPORT 定义为无。EXPORT
在一个稍微不同的话题上:在许多情况下,不可能(或不希望)导出这样的完整类。相反,您可能只想导出所需的符号。例如,在您的例子中,您可能只想导出两个公共方法。这样,所有私有/受保护的成员都不会被导出:
class xyz
{
public:
EXPORT void printing();
EXPORT void printing(int a);
};
评论
编译库时,您应该定义一个宏(命令行预处理器定义),我们将其称为 。MY_DLL_EXPORT
然后在库的代码中执行如下操作:
#ifdef MY_DLL_EXPORT
# define DLL_API __declspec(dllexport)
#else
# define DLL_API __declspec(dllimport)
#endif
class DLL_API some_class { /*...*/ }
我记得,通常情况下,您导出的不是类,而是创建类的新实例并返回指针的工厂函数。类声明驻留在头文件中,用于编译时。
我可能对这个例子是错误的(那是很久以前的事了),但这里它应该大致是什么样子的:
头文件 (.h):
class MyClass { ... };
extern "C" DLL_API MyClass* createMyClass();
源文件(.cpp):
DLL_API MyClass* createMyClass() {
return new MyClass();
}
在编译时定义MY_DLL_EXPORT,请参阅 foraidt 的答案示例。
评论
另一种选择:
使用项目本地默认定义的宏。
您可以在以下位置看到项目本地的默认定义宏:
属性 -> 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 {
//....
}
评论