CLR Dll UI创建太多表单

时间:2018-11-12 19:51:50

标签: c++ dll clr

所以我试图用c ++创建一个dll,当将其注入到进程中时会打开一个窗体。

这是我的代码(将文件与为表单生成的文件分开):

#include "Main.h"
#include <Windows.h>

using namespace::System;
using namespace::System::Windows::Forms;

auto FormRender(void) -> void {
    Hyperscanner::Main lpMain;
    lpMain.ShowDialog();

    return;
}

HANDLE g_Thread = nullptr;

auto __stdcall DllMain(HMODULE hMod, DWORD dwReason, void* lpReserved) -> int {
    if (dwReason) {
        g_Thread = CreateThread(nullptr, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>
            (FormRender), nullptr, 0, nullptr);
    }

    if (!dwReason) {
        TerminateThread(g_Thread, 0);
        CloseHandle(g_Thread);
        FreeLibraryAndExitThread(hMod, 0);
    }

    return true;
}

问题在于,由于某种原因,当我将其注入到进程中时,它会继续创建表单,例如线程中有一个循环,但是您看不到一个循环。而且,当我尝试在没有线程的情况下正常调用它时,它根本不会显示出来,这没有任何意义,因为从技术上讲,它与线程中的线程是同一件事。

我想知道自己做错了什么并且可以使用帮助。谢谢!

解决方案(通过@hacksalot):

问题在于,有许多线程正在启​​动,这些线程会通过我的DllMain回调,因此它将启动一堆线程(出于某种原因,我没有想到要检查创建了多少个线程)。

为解决此问题,我添加了一个全局变量以确保其仅执行一次。

#include "Main.h"
#include <Windows.h>

using namespace::System;
using namespace::System::Windows::Forms;

volatile int g_StartOnce = 0;

auto FormRender(void) -> void {
    Hyperscanner::Main lpMain;
    lpMain.ShowDialog();

    return;
}

auto StartRenderThread(HANDLE& ThreadHandle) -> bool {
    ThreadHandle = CreateThread(nullptr, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>
        (FormRender), nullptr, 0, nullptr);

    if (ThreadHandle)
    {
        return true;
    }

    return false;
}

auto StopRenderThread(HANDLE& ThreadHandle) -> bool {
    if (ThreadHandle) {
        if (TerminateThread(ThreadHandle, 0)) {
            CloseHandle(ThreadHandle);
            return true;
        }
    }

    return false;
}

HANDLE g_Thread = nullptr;

auto __stdcall DllMain(HMODULE hMod, DWORD dwReason, void* lpReserved) -> int {
    if (dwReason && !g_StartOnce) {
        StartRenderThread(g_Thread);
        ++g_StartOnce;
    }

    if (!dwReason) {
        StopRenderThread(g_Thread);
        FreeLibraryAndExitThread(hMod, 0);
    }

    return true;
}

1 个答案:

答案 0 :(得分:1)

来自documentation

  

您切勿在{{1​​}}内执行以下任务:

     

〜呼叫DllMain

另外CreateThreadFormRender回调签名不匹配,其调用会导致堆栈损坏。我什至不提CLR东西...

相关问题