16

我有一个可执行文件(我使用 Visual C++ 10 创建的),我需要从我编写的另一个程序(相同的环境)中使用它的功能。由于复杂的部署要求,我不会涉及,从所需的功能构建一个 DLL 并将其加载到两个程序中并不是我能做的事情。

所以我想,我可以__declspec(dllexport)在EXE中的一些功能,然后LoadLibrary()让我GetProcAddress()他们。

显然这是不可能的,尽管当我开始研究它时——它看起来是可行的。

具体来说,当您__declspec(dllexport)在 EXE 项目中运行时,Visual C++ 还会生成一个lib用于动态链接的文件——因此您甚至不需要使用LoadLibrary()——只需链接到生成的库并调用这些函数。

不幸的是,主要问题是当您将生成的文件声明为 EXE 时,Visual C++ 将“CRTmain”入口点添加到生成的文件中,而不是 DLL 获取的“CRTDLLmain”。当 Windows(自动)LoadLibrary()从您的主程序执行 EXE 时,它不会调用“CRTDLLmain”入口点(因为它不存在),模块的 C 运行时不会被初始化,因此所有有趣的工作(例如内存分配)因有趣的(*)运行时异常而失败。

所以如下,我的问题是:有没有办法让 Visual C++ 将“CRTmain”入口点“CRTDLLmain”入口点都构建到结果文件中?

(*) “有趣”,就像中国古老的诅咒一样。

4

3 回答 3

16

对的,这是可能的。

http://www.codeproject.com/Articles/1045674/Load-EXE-as-DLL-Mission-Possible

这个想法是 a) 修补 IAT 和 b) 在调用导出之前调用 CRT。

于 2015-11-11T20:44:01.707 回答
0

根本没有!问题是您要加载的 CRT 和 EXE 中使用了一些全局变量。您的主要 EXE 也是如此。那么内存分配应该如何工作呢?

如果您想使用这样的结构,您必须使用 DLL 来了解多线程、CRT 初始化以及所有其他内容。你需要这个!

但是 COM 自动化呢?在另一个 EXE 中使用您的代码不是一个简单的解决方案吗?

于 2013-10-01T08:13:05.450 回答
-2

最简洁的答案是不”。远看之后,没有办法让 VC++ 做我想做的事,而且很可能没有任何其他编译器。

主要问题是main()大多数人都知道和喜爱的入口点并不是 C++ 可执行文件的真正入口点:编译器需要做大量初始化工作才能使“C++ 运行时库”处于可用状态,以及初始化全局变量、静态变量等。这种初始化在共享库中使用与在可执行文件中不同的代码,并且没有办法让一个人表现得像另一个人。

可以做的一件事是将共享功能构建到 DLL 中,并让主可执行文件将 DLL 作为资源嵌入,并从可执行文件的内存映射区域加载它(有几个代码示例如何在 stackoverflow 和网络上的其他地方使用 VC++ 来做到这一点)。现在另一个程序可以通过从捆绑可执行文件中加载 DLL 来做同样的事情。

于 2014-04-22T16:05:14.467 回答