Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ cout和printf在Dll内置调试版本上工作_C++_Visual Studio 2010_Dll_Dll Injection - Fatal编程技术网

C++ cout和printf在Dll内置调试版本上工作

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&

我构建了一个DLL,通常通过SetWindowHookEx注入控制台应用程序。DLL将信息输出到控制台是很重要的,我一直在使用std::cout。DLL即将完成,直到我尝试在发布模式下构建DLL,这使得所有cout行都无用。我已经通过执行一个简单的空解引用来验证DLL是否正在注入和执行,这会导致程序在dllmain函数中崩溃。std::printf也是这样

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在我的整个项目中,你的帖子更多的是“建议”,而不是你在最后一句话中承认的答案。