导出DLL C++类,关于.def文件的问题
Exporting DLL C++ Class , question about .def file
我想在我的项目中使用隐式链接,而nmake确实想要一个.def文件。问题是,这是一个类,我不知道在导出部分应该写什么。有人能给我指正确的方向吗?
错误消息如下:
NMAKE:U1073:不知道如何制作"DLLCLASS.def"
p.S:我正在尝试使用WindowsCEPlatformBuilder进行构建。
如果我回忆正确,你可以在类上使用__declspec(dllexport)
,VC++将自动为与该类相关的所有符号(构造函数/析构函数、方法、vtable、typeinfo等)创建导出。
Microsoft在此处提供了有关此方面的详细信息。
您总是可以通过使用dumpbin/symbols myclass.obj 找到成员函数的装饰名称
在我的情况下是
class A {
public:
A( int ){}
};
dumpbin
转储显示符号??0A@@QAE@H@Z (public: __thiscall A::A(int))
将此符号放入.def文件会导致链接器在导出符号中创建A::A(int)符号。
但是正如@paercebal在他的评论中所说:手动输入修饰(损坏)的名称是一件麻烦的事——很容易出错,而且很遗憾,不能保证在编译器版本之间移植。
我找到了成为抽象工厂的最佳途径。
首先定义一个纯虚拟基类。这是一个没有实现的类,一个纯粹的虚拟接口类。
你可以导出这个虚拟的基本"抽象接口"类,但没有真正的理由这样做。当调用者使用它时,他们将通过指针(PImpl或pointer to Implementation)使用它,所以调用者只知道一个简单的内存地址。Def文件虽然还有一点点工作要做,但它提供的好处超出了__declspec(dllexport)所能达到的。你会问,有什么好处?我们会做到的,你就等着吧。
让您的真实类从虚拟库公开继承。现在创建一个工厂方法来构造对象,并创建一个"release"式的可调用析构函数来执行清理。将这些方法命名为"ConstructMyClass"answers"ReleaseMyClass"。请替换"MyClass":-)
如果这些工厂/发布方法需要任何参数(普通的旧数据:integer、char等),那么它们应该只接受POD类型。返回类型应该是虚拟抽象接口基类,或者更确切地说,是指向它的指针。
IMyClass*CreateAnObjectOfTypeIMyClass();
也许现在我们需要虚拟基类的原因已经很明显了?由于虚拟接口类没有实现,它本质上都是POD类型(有点),因此类的"数据类型"可以被大多数调用程序(如Visual Basic、C或截然不同的C++编译器)所理解。
如果你足够喜欢,你可以绕过对"手动发布"方法的需求(对不起,不得不这么做)。怎样通过智能指针和pImpl类型的体系结构来管理类中自己的资源,这样当对象死后,它就会自行清理。这样做意味着,用我们的圣人和救世主Scott Meyers不朽的话来说,通过让调用者忽略清理的必要性,你的类是"易于正确使用,难以错误使用"。让我们当中那些从未忘记呼唤".close"的人铸造第一块石头。
也许这个架构听起来很熟悉?它应该,它基本上是COM的一个微机器版本。嗯,至少是接口、工厂构建和发布的概念。
最后,您导出了类的接口,制作(并导出)了Create和Destroy方法,现在调用方可以调用PleaseConstructMyClass工厂函数,让DLL在其接口的伪装下返回一个完全构造、完全实现和完全烘焙的对象。他们可以调用类的所有公共方法(至少是抽象虚拟接口中的方法),并做所有有趣的事情。
当他们处理完工厂函数返回的对象时,他们可以调用"ReleaseMyClass"函数来要求DLL清理对象的资源,或者你可以通过让你的类自己清理来帮助他们,使"ReleaseMyClass"方法变得多余和无用。
如果有人对具体收益感兴趣&使用Def文件和接口的权衡(除了我盲目地这么说),请耐心等待,我们可以更深入地挖掘。
你不就是喜欢这个东西吗?
解决方案如下:
-
由于导出了类,您还需要在.def文件中添加导出的方法
-
我没有找到如何导出构造函数,所以我使用了一个工厂方法(静态),它将返回对象的新实例
-
其他函数将通过在.def文件中添加正常导出声明来导出
希望有人能从这些信息中受益。
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 在使用 Clang 编译 DLL 时指定 DEF 文件
- C++ 如何在 def 文件中指定命名空间
- 使用 .def 文件的优缺点
- 访问使用 def 文件导出的静态变量时崩溃
- 使用 DEF 文件删除 dll 导出的名称
- 挂钩在Linux上通过.def文件上的功能
- 当函数通过.def文件导出时,如何使用dllImport导入函数
- .def文件相当于OS X
- 在 .def 文件中使用 DATA 的定义未解析的外部符号
- 什么是 c++ 项目中的 *.def 文件
- 创建 MSVC 库的完整 DEF 文件
- Windows __stdcall DLL 的 DEF 文件格式?(*.def -> lib.exe -> *.lib)
- 使用def文件从可执行文件导出函数
- bcc32 + nasm obj 链接错误(致命:"fir.asm":需要在 .def 文件中定义其他段)
- 在def文件中导出修饰函数名
- 如何使用 def 文件在 de dll 中使用 mfc
- .def 文件与 __declspec(dllexport) 宏
- 导出DLL C++类,关于.def文件的问题