当使用Windows可执行文件作为DLL时,如何初始化C运行时
How to initialize the C runtime when using a Windows executable as a DLL
我正在尝试在我的Windows可执行文件中做类和函数的单元/组件测试。我想运行实际编译的代码,而不将测试用例构建到可执行文件*中。微软的工具非常乐意从可执行文件中导出类和函数,我可以链接到它,就好像它是一个DLL。捕获-由于动态加载的可执行文件的入口点没有被调用,并且没有DllMain(从技术上讲,它不是DLL), C运行时没有在"DLL"中初始化,静态量也没有初始化**。
是否有一种方法可以在动态加载的。exe的上下文中调用CRT_INIT并使一切正常工作,或者这是荒谬的?
*如果我在这里遗漏了一些明显的东西,请随时为我指出正确的方向。
**这是我最大的问题
免责声明-我坚持我原来的答案。这应该不能工作。最佳实践是将核心代码编译为LIB或DLL,然后将该库链接到UnitTest代码和主程序代码中。
但是自从OP向我展示了他确实找到了一种使EXE作为DLL工作的方法,我觉得有必要把剩下的方法带给他…
技巧是调用_CRT_INIT。但是,由于没有调用DllMain来获取HINSTANCE句柄,您必须直接调用GetModuleHandle来获取它。然后我保留一个表来跟踪哪些线程为它调用了CRT_INIT。我采用了他提供的示例代码,并在AppToTest.exe代码中添加了这个数据结构:
bool g_isProcessInitialized = false;
std::map<DWORD, bool>* g_threadmap;
extern "C" BOOL __stdcall _CRT_INIT(HINSTANCE, DWORD, void*);
void ThreadInit()
{
std::map<DWORD, bool>& themap = *g_threadmap;
DWORD dwCurrentThreadID = ::GetThreadId(GetCurrentThread());
if (themap[dwCurrentThreadID] == false)
{
_CRT_INIT(GetModuleHandle("AppToTest.exe"), DLL_THREAD_ATTACH, NULL);
themap[dwCurrentThreadID] = true;
}
}
void ProcessInit()
{
if (g_isProcessInitialized == false)
{
_CRT_INIT(GetModuleHandle("AppToTest.exe"), DLL_PROCESS_ATTACH, NULL);
_CRT_INIT(GetModuleHandle("AppToTest.exe"), DLL_THREAD_ATTACH, NULL);
g_isProcessInitialized = true;
g_threadmap = new std::map<DWORD, bool>();
std::map<DWORD, bool>& themap = *g_threadmap;
themap[GetThreadId(GetCurrentThread())] = true;
}
}
void APPAPI InitializeCRT()
{
ProcessInit();
ThreadInit();
}
然后在TestApp.exe中,我修改了"main"以提前调用InitializeCRT:
int main(int argc, char* argv[])
{
InitializeCRT();
这似乎是有效的-即使在我取消了对标记有问题的方法的调用的注释之后。如果创建了后续线程,那么这些线程可能需要调用InitializeCRT。(它可能会工作…)
我不敢相信这真的有效。可能不适用于旧版本的Windows。
这行不通。不能像加载DLL一样动态加载EXE。有一些有限的场景涉及从EXE加载资源,但没有导出函数。
你最好把除了WinMain以外的所有东西编译成LIB或DLL。然后链接你的UnitTest.EXE和YourProgram.EXE(每个提供main或WinMain的实现)到这个库。
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- 在构造函数 c++ 中初始化属性时出现问题
- 使用初始化列表时如何获取私有数据?
- 在MSDOS编译器上,用大于最大值的值初始化int时输出混乱
- 有没有办法在初始化字符串时避免来自 clang-tidy(fuchsia-default-arguments)的警告?
- 在构造函数中初始化成员时,是否应该在成员上使用 std::move?
- 我想知道在构造函数中初始化变量时的生命周期
- 初始化指针时出现写入访问冲突
- 初始化对象时引发错误
- 初始化对象时,可以丢弃新的返回值吗?
- 用struct初始化C 向量时的构造函数误差
- 在类构造函数中初始化映射时,如何避免内存泄漏
- 通过在此指针上放置新位置重新初始化对象时未定义的行为
- 使用静态常量初始化unique_ptr时出现未定义的引用错误
- 当数量小于初始化索引时确定数组中元素数的方法
- 初始化 bgfx 时遇到问题(使用 sdl2 窗口)
- 从模板类初始化对象时出错.参考类模板实例化
- CRT初始化:运行时错误 - CRT未初始化
- 当使用Windows可执行文件作为DLL时,如何初始化C运行时