首页 > 解决方案 > DllMain w/createthread 和 printf

问题描述

我正在尝试使用 mingw-64 构建一个 Windows dll,一旦加载,它就会开始无限地打印“Hello World”。

这是我的 dll.c

#include <stdio.h>
#include <windows.h>
#include "dll.h"
#include "main.h"

HINSTANCE hThisModule;


DWORD mainThread() {
    while(1) {
        printf("Hello world!");
    }
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
    static HANDLE hThread;
    hThisModule = hinstDLL;

    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            hThread = CreateThread(0, 0, mainThread, 0, 0, 0);
            break;

        case DLL_PROCESS_DETACH:
            break;

        case DLL_THREAD_ATTACH:
            break;

        case DLL_THREAD_DETACH:
            break;
    }

    return TRUE;
}

void dummy() {
    Hello();
}

这是我的 dll.h:

#ifndef DLL_H_
#define DLL_H_

#ifdef BUILD_DLL
/* DLL export */
#define EXPORT __declspec(dllexport)
#else
/* EXE import */
#define EXPORT __declspec(dllimport)
#endif

#endif /* DLL_H_ */

所以我构建了一个简单的程序来加载我的 DLL 以查看它是否正常工作,这里是:hello.cpp

#include <windows.h>
#include <iostream>

typedef int (__stdcall *f_funci)();

int main()
{
  HINSTANCE hGetProcIDDLL = LoadLibrary("./wow.dll");

  if (!hGetProcIDDLL) {
    std::cout << "could not load the dynamic library" << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

现在,当我将 hello.cpp 编译为 hello.exe 并将 dll.c 编译为 wow.dll 时,我的控制台上什么也没有。怎么了?

标签: c++winapi

解决方案


首先,我想提一下,在你的线程中实现这样一个繁忙的循环是不可取的。

至于您遇到的问题,这里有几个潜在的问题:

  1. printf是 CRT 函数,但是您调用的是CreateThread()而不是beginthread(ex),因此 CRT 未正确初始化。
  2. DLL 入口点是一个出了名的问题所在。您几乎不能从那里调用任何 kernel32 函数,更不用说 CRT 函数了(请参阅DllMain 入口点动态链接库最佳实践)。

在大多数情况下,建议实现客户端在使用您的库时需要调用的单独函数InitExit


推荐阅读