LoadLibrary()一个EXE?

Gus*_*uss 11 c windows visual-studio-2010 visual-c++

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

所以我认为我可以__declspec(dllexport)在EXE中使用某些功能,然后LoadLibrary()就让我们GetProcAddress()了.

显然,这是无法做到的,尽管当我开始研究它时 - 它看起来很可行.

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

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

如下所示,我的问题是:有没有办法使Visual C++在结果文件中构建"CRTmain"入口点 "CRTDLLmain"入口点?

(*)像中国古老的诅咒一样"有趣".

Mic*_*kis 11

对的,这是可能的.

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

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

  • 哇,那里有一些深刻的魔力.我不再在那个项目上工作了,但尝试会很有趣,尽管我不了解IAT修补代码中发生的一半. (2认同)

Gus*_*uss -3

最简洁的答案是不”。经过广泛考虑,没有办法让 VC++ 做我想做的事情,很可能任何其他编译器都做不到。

主要问题是main()大多数人知道和喜欢的入口点并不是 C++ 可执行文件的真正入口点:编译器需要做大量的初始化工作才能使“C++ 运行时库”达到可用状态,以及初始化全局变量、静态变量等。此初始化在共享库中使用与可执行文件中不同的代码,并且无法使一个库的行为与另一个库的行为相似。

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