Jam*_* R. 13 c++ windows dll gcc g++
我正在使用MinGW工具链构建一个Windows动态库.
为了构建这个库,我静态地链接到提供API的其他2,我有一个.def文件,我写了我想要在我的库中导出的唯一符号.
问题是GCC正在导出所有符号,包括我链接到的库中的符号.反正告诉链接器只是导出def文件中的符号?
我知道有选择,--export-all-symbols但似乎没有相反的选择.
现在,构建脚本的最后一行具有以下结构:
g++ -shared CXXFLAGS DEFINES INCLUDES -o library.dll library.cpp DEF_FILE \
OBJECT_FILES LIBS -Wl,--enable-stdcall-fixup
Run Code Online (Sandbox Code Playgroud)
编辑:在关于链接器的文档中,它表示这--export-all-symbols是默认行为,并且如果您提供def文件时未明确使用该选项则禁用它,除非它没有; 无论如何,第三方库中的符号正在导出.
编辑:添加选项--exclude-libs LIBS或–exclude-symbols SYMBOLS不阻止导出库中的符号.
不知道为什么没有真正的答案,但这对我有用:
编译目标文件:
g++ -O0 -gdwarf-4 dll\dllmain.cpp -c -o dllmain.o
Run Code Online (Sandbox Code Playgroud)链接(-Wl,--exclude-all-symbols很重要):
g++ -Wl,--enable-auto-import -Wl,--out-implib,libsomelib.a -Wl,--exclude-all-symbols -shared dllmain.o -o somelib.dll
Run Code Online (Sandbox Code Playgroud)然后您选择直接在 DLL 的源代码中导出哪些函数:
#include <windows.h>
__declspec(dllexport) void someExportedFunction() {
MessageBox(NULL, "msgbox", "msgbox", MB_OK);
}
void nonExportedFunction() {
MessageBox(NULL, "notexported", "notexported", MB_OK);
}
Run Code Online (Sandbox Code Playgroud)
确认:
C:\libtest>pedump -E somelib.dll
=== EXPORTS ===
# module "somelib.dll"
# flags=0x0 ts="2014-02-20 08:37:48" version=0.0 ord_base=1
# nFuncs=1 nNames=1
ORD ENTRY_VA NAME
1 1570 _Z20someExportedFunctionv
Run Code Online (Sandbox Code Playgroud)
( pedump= http://pedump.me )
如果您的 binutils 发行版(本机或交叉编译)提供了 dllwrap,则可以使用 dllwrap。
它可以使用 DEF 文件中的接口生成 DLL(在幕后它调用 gcc、ld 和 dlltool 来执行此操作)。使用此方法与直接将 DEF 文件传递给 GCC 的区别在于文件中的定义的处理方式不同。
例如,如果导出文件中有符号重命名:
_SomeFuntion = _SomeFunction@12
Run Code Online (Sandbox Code Playgroud)
GCC 将创建 2 个导出,一个名为_SomeFunction,另一个具有修饰名称,而 dllwrap 只会导出_SomeFuntion。因此,如果您只将想要导出的符号添加到 DEF 文件中,那么最终库中只会包含它们。
dllwrap 默认使用 C 编译器驱动程序,因为它无法知道其他情况。当您链接 C++ 代码时,您必须使用该选项--driver-name c++来设置驱动程序。如果您碰巧拥有带有前缀的 MinGW 可执行文件,您也必须将其包含在驱动程序名称中(例如,i686-mingw32-c++而不是c++),并且您可能也需要使用该选项--dlltool-name。
尝试使用这两行而不是您发布的那一行:
g++ -c CXXFLAGS DEFINES INCLUDES -o library.o library.cpp
dllwrap -o library.dll --driver-name c++ --def DEF_FILE OBJECT_FILES LIBS -Wl,--enable-stdcall-fixup
Run Code Online (Sandbox Code Playgroud)
第一个从代码生成目标文件library.cpp,第二个编译动态库。这个OBJECT_FILES东西(我假设是您之前生成的其他目标文件)library.o也应该在那里。
也就是说,我必须告诉您 dllwrap 已在 2006 年被弃用,并且官方 binutils 软件包中没有关于它的文档;要获取一些信息,您可以像往常一样调用它--help。它可以生成一个导入库,以防您也需要。
| 归档时间: |
|
| 查看次数: |
11420 次 |
| 最近记录: |