将类从可执行文件导出到 dll
Posted
技术标签:
【中文标题】将类从可执行文件导出到 dll【英文标题】:Exporting class from executable to dll 【发布时间】:2009-02-27 13:21:38 【问题描述】:我需要在 DLL 中使用在可执行文件中定义的类(DLL 和可执行文件由同一个编译器编译)。但是我不希望这个类定义的源代码对 DLL 可用,只有声明。
一种可能的方法是将所有必要的类方法设为virtual
(这样DLL 链接器就不需要这些方法的定义)。这种方法的缺点:
-
我无法创建导出类的对象
在使用
new
的 DLL 代码中(必须
在中创建附加功能
可执行文件的代码)。
我必须使所有这些方法virtual
,
即使他们不需要
是virtual
。
有一种方法可以使用 Microsoft 的 __declspec(dllexport)
storage-class 扩展属性将类从 DLL 导出到可执行文件。
有没有办法使用相同的技术将类从可执行文件导出到 DLL?
我的旧 Borland C 6 编译器不允许我在构建可执行项目期间创建导入库。 (因此,在编译 DLL 时,链接器会为所有导入的非虚拟类方法提供未解决的外部错误消息。)这是这个编译器的限制,还是我遗漏了一些重要的东西?
【问题讨论】:
【参考方案1】:据我所知,使用 MS VS 的 dllexport 从 exe 导出类或函数并在 DLL 中使用它是可以的。如果您的 DLL 和 Exe 在一个进程中执行,它运行起来很酷。
【讨论】:
是的,你是对的。刚刚在 MS VS 2008 上尝试过 - 可以为具有所有 __declspec 符号的可执行文件生成导入库,并将其与 dll 链接。所以,这似乎是我的旧 Borland C++ 6.0 编译器的限制。谢谢。 添加注释,如果您使用 exe 中的 DEF 文件导出符号,则您的 exe 将不再能够运行。【参考方案2】:如果您真的不希望在第一个 DLL 中将该类放入第二个 DLL。
我很难理解您为什么不只是将类放入 DLL 中。
ETA: 做了一些更深入的挖掘,发现this link 解释了如何在 Visual Studio 2008 中从 EXE 项目生成导入库。至于如何导出它们,看起来你只是使用常规的 __declspec(dllexport)。
【讨论】:
例如,这个类代表一些 API,应该在 DLL 中使用。 DLL 由第三方开发。有一个“诀窍”问题是不让 API 实现外部给第三方。不过,将这个 API 类放在另一个 DLL 中就可以了,谢谢。 从可执行文件中导出符号太可能了。必须是,DLL 是可执行文件。 示例:ntoskrnl.exe 已导出符号。 有趣,我认为不可能做到这一点。我编辑了答案并删除了那里的不准确信息。每天学习新东西:)【参考方案3】:好的,根据此处的新信息提供新答案。如果你不能用你的编译器为你的 EXE 生成一个导出库,而你真的必须这样做,这里有一个创造性的、hacky 且通常不推荐的解决方案:
第 1 步:为你的类创建一个 C 包装 API,有点像这样(可能不会编译,但你明白了):
// Yes, need some 32 bit/64 bit checks here
#define MYHANDLE unsigned int
__declspec(dllexport) MYHANDLE MyClassNewInstance()
MyClass* ptr = new MyClass();
return (MYHANDLE)ptr;
__delspec(dllexport) MyClassDoSomething( MYHANDLE handle, int parm )
MyClass* ptr = (MyClass*)handle;
ptr->DoSomething(parm);
etc..
第 2 步:要真正从 EXE 中获取 C 函数以在 DLL 中使用,请使用 Win32 API 函数 GetModuleHandle() 和 GetProcAddress()。
第 3 步:在 DLL 中创建代理类。代理类中的方法只是从 EXE 中调用它们对应的 C 函数。
这将使您的类的“真实”实现远离 DLL。这是一个 hack,但它可能会起作用。
【讨论】:
以上是关于将类从可执行文件导出到 dll的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 Windows 上运行时从可执行文件中定位函数?