没有编译依赖项的 DLL

DLL with no compiled dependencies

提问人:Stryker2k2 提问时间:7/12/2023 最后编辑:HolyBlackCatStryker2k2 更新时间:7/12/2023 访问量:41

问:

我正在尝试以尽可能小的方式使用 mingw32 (x86_64-w64-wingw32-gcc) 编译 DLL。

我有一个运行的可执行客户端,它具有DLL所需的所有依赖项,例如json.c和base64.c。

与其将 json.c 和 base64.c 编译到 DLL 中,我宁愿找到一种方法来忽略“未定义的引用”错误,让 DLL 从可执行客户端的 json.c 和 base64.c 中提取函数。

因此,我的问题。如何使用 mingw 编译这个零依赖 DLL?

我试过了,但没有用。该选项有效...但 GCC 错误输出是相同的。-Wl,--unresolved-symbols=ignore-all

在这里,我有一个定义了函数的可执行文件,我正在尝试编译这个DLL以具有一个未解析的符号,当DLL这样做时,将调用该符号,该符号应该(希望)在我启动后启动。printSuccess__declspec(dllimport)DLL_PROCESS_ATTACHprintSuccessLoadLibrary & GetProcAddress

这是输出:

dev@CLIENT2:/$ x86_64-w64-mingw32-gcc main.c -Wl,--unresolved-symbols=ignore-all -o main64.exe

main.c: In function ‘main’:
main.c:10:2: warning: implicit declaration of function ‘printSuccess’ [-Wimplicit-function-declaration]
   10 |  printSuccess();
      |  ^~~~~~~~~~~~
/usr/bin/x86_64-w64-mingw32-ld: /tmp/cctVzHaX.o:main.c:(.text+0x15): undefined reference to `printSuccess'
collect2: error: ld returned 1 exit status
C GCC mingw 未解析 - 外部

评论

0赞 Ben Voigt 7/12/2023
在 Windows 中,DLL 可以从加载 DLL 的 EXE 导入符号,但 EXE 必须具有一个有点不寻常的导出表。您可以对 EXE 进行更改吗?
0赞 HolyBlackCat 7/12/2023
你的代码在哪里?你忘了把你的函数声明为吗?__declspec(dllimport)
0赞 Stryker2k2 7/12/2023
我可以对EXE进行更改,是的。但是,即使我在EXE中制作了一个导出表,我仍然不知道如何编译DLL来利用它。
1赞 HolyBlackCat 7/12/2023
首先,请在回复时添加您的评论,否则我们不会收到通知。@username
0赞 Ben Voigt 7/12/2023
使用导出生成 EXE 时,将创建一个导入库(就像使用 DLL 一样)。将该导入库传递给 DLL 生成过程。这将消除未解析的外部问题(因为链接器将在 DLL 中创建一个导入表,该表与 EXE 中的导出表匹配)。

答:

-1赞 rgnt 7/12/2023 #1

好吧,因为编译器在链接时需要函数存在,因为必须查找地址,所以您尝试做的事情是不可能的。

我的建议是将 json 和 base 实际移动到不同的模块,然后可执行文件和其他 DLL 可以依赖这些模块。

评论

0赞 Ben Voigt 7/12/2023
链接器需要一个导入库,然后函数在链接期间不会出现 - 地址将由加载器匹配。这就是 EXE 使用 DLL 函数的方式......也可以使用EXE中的函数。
0赞 Stryker2k2 7/12/2023
我也不反对“CommonDependencies.dll”。老实说,我可能真的更喜欢它,@BenVoigt。假设这是一个很好的游戏计划,我将如何进行?我会用所需的编译 CommonDeps.dll 并让 EXE(和后续的模块 DLL)用所需的编译,然后,一旦我做了一个 LoadLibrary(CommonDeps.dll),那么一切都应该神奇地链接起来?然后我可以创建和读取json字符串吗?dllexportsdllimports
0赞 Ben Voigt 7/12/2023
@Stryker2k2:导入表将命名,加载器将自动加载它...无需或致电。拥有一个 EXE 和其他 DLL 都使用的通用 DLL 绝对是更常见的方法,并且推荐使用,因为它避免了循环导入。CommonDeps.dllLoadLibrary()GetProcAddress()