本机dll从C#中踢出,没有错误消息

时间:2019-07-16 15:23:23

标签: c# c++ multithreading dll

在我看来,C#似乎踢出了本机dll。我如何找出原因或预防这种行为?

我有一个(大型)c#应用程序(win32)。对于一些时间紧迫的功能,我写了一个本地c ++ dll。根据用户命令,在启动线程的dll中调用了(start-)函数。作为参数,将在调用中传递winforms面板的窗口句柄。该线程的输出在该窗口中显示。线程运行时,面板不做任何改动。线程无休止地运行,直到用户在dll中终止该线程的stop函数。到目前为止,一切正常/按预期进行。

但是,DLL有时每隔一段时间就会消失。输出冻结,无需任何用户操作。似乎该dll已从内存中删除。当用户随后调用stop函数时,dll接缝将被重新加载,告诉用户该线程之前未启动。没有运行时错误,没有消息,什么也没有。我找不到追踪该错误的方法。有没有办法让C#告诉它为什么将dll踢出内存?还是我可以以某种方式钉住dll,以便无法将其踢出?有什么工具可以帮助我吗?

dll:
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {
    UNREFERENCED_PARAMETER(lpReserved);
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        g_RunOutputThread = false;
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
    }
    return TRUE;
}

MYDRIVER_API long  Start(HWND houtputwindow){
    if(g_RunOutputThread) return -1; //thread already running
    g_RunOutputThread = true;
    g_OutputThread = thread(&OutputThreadFunction);
    return 0;
}

MYDRIVER_API long  Stop(){
    if(!g_RunOutputThread) return -1; //thread was not started
    g_RunOutputThread = false; // the only line (beside dllmain) that set this to false
    if (g_OutputThread.joinable()) g_OutputThread.join(); 
}



void DisplayThreadFunction(){
    try{
        while (g_RunOutputThread) {
        ... // the timecritacal work
        }
    }catch(...){
        MessageBox(NULL, L"Error in output loop!"...// does not appear!
    }
}


c#
[DllImport("MyDriver.dll", CallingConvention = CallingConvention.Cdecl)]
private extern static int Start(IntPtr hWndOutput);

[DllImport("MyDriver.dll", CallingConvention = CallingConvention.Cdecl)]
private extern static int Stop();


void OnStartButton_Click(){
    int ret = Start(pnOutput.Handle);
}

void OnStop_Click(){
    int ret = Stop();
}

1 个答案:

答案 0 :(得分:0)

感谢dorKKnight,当我终于找到导致异常行为的原因时,我开始执行它,该dll没有从内存中删除,它只是接缝了:从具有计时器的对话框中调用该dll,该计时器调用了stop函数一段时间后。当对话框“中止”时,计时器没有停止(我不好),而再次打开对话框时,该计时器仍在运行,并称为停止功能,导致意外结束(冻结)。而且,当然,当用户调用停止功能时,状态再次变为“未启动”,就像第一次加载dll一样。