C++ cout和printf在Dll内置调试版本上工作
我构建了一个DLL,通常通过SetWindowHookEx注入控制台应用程序。DLL将信息输出到控制台是很重要的,我一直在使用std::cout。DLL即将完成,直到我尝试在发布模式下构建DLL,这使得所有cout行都无用。我已经通过执行一个简单的空解引用来验证DLL是否正在注入和执行,这会导致程序在dllmain函数中崩溃。std::printf也是这样C++ cout和printf在Dll内置调试版本上工作,c++,visual-studio-2010,dll,dll-injection,C++,Visual Studio 2010,Dll,Dll Injection,我构建了一个DLL,通常通过SetWindowHookEx注入控制台应用程序。DLL将信息输出到控制台是很重要的,我一直在使用std::cout。DLL即将完成,直到我尝试在发布模式下构建DLL,这使得所有cout行都无用。我已经通过执行一个简单的空解引用来验证DLL是否正在注入和执行,这会导致程序在dllmain函数中崩溃。std::printf也是这样 void onAttach() { //WARNING THIS IS A DEMONSTRATION std::cout&
void onAttach()
{
//WARNING THIS IS A DEMONSTRATION
std::cout<<"test"<<std::endl;
//int* intPtr = 0;
//*intPtr = 3; //This causes a crash
}
// entry point
BOOL WINAPI DllMain ( HMODULE hModule, DWORD dwReason, LPVOID lpReserved )
{
switch ( dwReason )
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls ( hModule );
CreateThread ( NULL, 0, ( LPTHREAD_START_ROUTINE ) onAttach, NULL, 0, NULL );
return true;
break;
case DLL_PROCESS_DETACH:
return true;
break;
}
}
void-onAttach()
{
//警告:这是一次演示
std::cout您不应该在DllMain中执行任何依赖于另一个DLL的操作。您至少违反了三次:printf
和std::cout
依赖于CRT(反过来依赖于Win32 DLL)和CreateThread
依赖于Kernel32.DLL
DllMain
用于变量归零等简单操作。我知道@salters指出不应在DLL中调用其他库是正确的,但经过反复试验,我发现在x64配置(而不是x86)中编译DLL时,DLL可以“cout”或使用“MessageBox”没有任何问题的函数(可能从许多其他库调用函数)。希望这有帮助:)。我怀疑stdout
正在调试中刷新,但在发行版中没有。很遗憾,尝试std::cout使用endl与cout使用相同的情况。printf
调用不会刷新输出。它还使用了std::cout
的不同缓冲区,因此您真的不应该混合使用这些缓冲区。您是否链接到DLL vC运行时()的版本?如果您使用WriteFile(GetStdHandle(STD\u OUTPUT\u HANDLE),“test”,4,NULL,NULL)
而不是使用printf
或cout
,您能打印到控制台吗?@AdamRosenfield啊,谢谢。WriteFile有效。有什么理论解释为什么会这样吗?我试着调用STD::cout.flush()虽然换行符应该可以。叹气,这只是一些基本的代码来表达观点。请发挥你的想象力,假装它在onAttach函数中,好吗?更不用说这根本不能回答这个问题。我很感激所有的答案,但这似乎更像是一个戳而不是一个答案。@Slight:D中代码的行为llMain非常不可预测,并且严重依赖于DLL加载顺序。因为调试版本将依赖于不同的DLL(例如ToolHelp.DLL),这几乎是给定的DLL加载顺序不同。因此,仅在DllMain中有这样的代码就足以解释观察到的行为。显然,我无法根据您没有向我们展示的代码提供答案。@salters我的代码正在被注入。从今往后,您可以假设我的DLL是最后加载的。我还提到我有std::cout u在我的整个项目中,你的帖子更多的是“建议”,而不是你在最后一句话中承认的答案。