【问题标题】:Create a Windows shared library with DllMain function (MinGW + CMake)使用 DllMain 函数创建 Windows 共享库(MinGW + CMake)
【发布时间】:2015-04-07 11:27:34
【问题描述】:

如果有人问过这个问题,我深表歉意,但我已经努力寻找答案好几个星期了。

在共享库方面我不是特别胜任,但是,使用 MinGWCLion RC 1.0(及其集成的 CMake)时,我无法使用 DllMain 函数创建功能 Windows DLL .我确实设法创建了一个.dll 文件,但很快就发现该符号没有正确导出。

简单地说,我希望看到与使用 Visual Studio 的默认 Win32 DLL 模板获得的行为相同或相似的行为。

CMakeLists.txt

cmake_minimum_required(VERSION 3.1)
project(DllMainTest)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SOURCE_FILES main.cpp)
add_library(DllMainTest SHARED ${SOURCE_FILES})

main.cpp

#include <windows.h>

extern "C" BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,
    DWORD fdwReason,
    LPVOID lpvReserved
) {
switch(fdwReason) {
    case DLL_PROCESS_ATTACH:
        MessageBox(NULL, "It works!", "Status", MB_OK);
    case DLL_PROCESS_DETACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    default:
        break;
    }
return TRUE;
}

编辑: 此 DLL 的目的是将其注入 32 位进程并在加载时显示 MessageBox。

【问题讨论】:

  • 请向我们展示您的 CMakeLists.txt 并完成主要功能。
  • DllMain 调用 user32.dll 函数 (MessageBox) 几乎肯定迟早会导致死锁。详情请见Dynamic-Link Library Best Practices
  • 另请注意,extern "C" 存储类说明符指示编译器使用 C 名称修改(当编译为 C++ 时)。它不会导致导出表中的条目。使用 __declspec(dllexport) 从 DLL 中导出符号。未能使用break 语句可能意味着您不应该将代码注入到另一个进程中。
  • @IInspectable 我了解加载程序锁定的想法(这只是一个示例/PoC),但感谢您提醒我,我一定会创建一个线程。感谢__declspec(dllexport) 的想法,但我必须对break 的评论提出异议。执行不应该落入默认情况并在那里中断(Fallthrough)吗?
  • @Antonio 全球 C++ 编程社区拥有的各种学说使约定变得模棱两可,充其量是微不足道的。让我们不要闯入被对比鲜明的激情污染的空间,并专注于手头的问题,除非这种明显的非法行为是导致此类问题的原因。

标签: c++ windows dll cmake mingw


【解决方案1】:

查看 add_library 文档:http://www.cmake.org/cmake/help/v3.0/command/add_library.html

“静态库是链接其他目标时使用的目标文件的存档。共享库是动态链接并在运行时加载的。模块库是不链接到其他目标但可以在运行时使用 dlopen-like 动态加载的插件功能”

add_library(DllMainTest MODULE ${SOURCE_FILES})

应按预期导出 DllMain。

【讨论】:

  • 感谢您的回答,虽然它看起来很有希望(并且确实适用于我的用例),但 DLL 注入仍然失败。
  • 嗯。在创建用于注入的 dll 时,这对我来说很好。也许您现在应该跳过注入并创建一个尝试加载库的小 exe。检查 LoadLibrary 的返回值,并使用 GetLastError 获取错误代码。请参阅有关 LoadLibrary 的 msdn 文章。只是在黑暗中拍摄:您想注入 32 位进程。您安装了 64 位版本的 mingw,默认情况下会创建一个 64 位 dll,这将无法加载到 32 位目标中。
  • @user1283078 我相信构建一个 32 位版本的 DLL 你可以在 CMakeLists.txt 文件中使用这个命令:set_target_properties(DllMainTest PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")跨度>
猜你喜欢
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-30
  • 2023-03-03
  • 2020-01-17
  • 2013-07-10
相关资源
最近更新 更多