Gcc “-Wl,-soname”是否适用于MinGW,或者是否存在等效项?

Gcc “-Wl,-soname”是否适用于MinGW,或者是否存在等效项?,gcc,dll,mingw,mingw-w64,dllexport,Gcc,Dll,Mingw,Mingw W64,Dllexport,我正在尝试使用MINGW在windows上构建dll 我认为一个非常好的总结可以在以下网站找到: 甚至还有一个基本项目可用于本次讨论: 请注意,此项目中存在一个表面错误,这将使其无法正常运行:Makefile不创建obj目录-请调整Makefile或手动创建它 所以这才是真正的问题。 如何更改Windows DLL名称,使其与实际DLL文件名不同?? 基本上,我正在尝试在Windows上实现这个效果,Linux上的效果在这里得到了很好的描述: 最初,我尝试在用于创建DLL的资源文件中更改I

我正在尝试使用MINGW在windows上构建dll

我认为一个非常好的总结可以在以下网站找到:

甚至还有一个基本项目可用于本次讨论:

请注意,此项目中存在一个表面错误,这将使其无法正常运行:Makefile不创建obj目录-请调整Makefile或手动创建它

所以这才是真正的问题。 如何更改Windows DLL名称,使其与实际DLL文件名不同?? 基本上,我正在尝试在Windows上实现这个效果,Linux上的效果在这里得到了很好的描述:

最初,我尝试在用于创建DLL的资源文件中更改InternalName和OriginalFilename,但这不起作用

在第二步中,我尝试在执行最终链接的命令上添加-Wl、-soname、soname.dll,以更改Windows dll名称

但是,这似乎没有达到我使用的mingw7.3.0、x86_64-posix-seh-rev0的预期效果。 有两件事让我这么说:

1/测试可执行文件仍然工作,我预计它会失败,因为它试图定位SoName.dll,但找不到它

2/pexports.exe AddLib.dll生成以下输出,其中库名称未更改:

LIBRARY "AddLib.dll"
EXPORTS
Add
bar DATA
foo DATA
我做错什么了吗?我的期望可能是错的吗

谢谢你的帮助!
David

首先,我想说的是,使用.def文件指定导出的符号或使用uu declspecdllexport/u declspecdlimport非常重要,但决不能将这两种方法混合使用。还有另一种方法使用-Wl,-export-all-symbols链接器标志,但我认为这很难看,应该只在快速和肮脏是你想要的时候使用

可以告诉MinGW使用与库名称不匹配的DLL文件名。在链接步骤中,使用-o指定DLL,使用-Wl,-out implib指定库文件

让我通过演示如何构建静态库和共享库来进行说明。它的源代码只包含两个文件:chebyshev.h和chebyshev.c

编写 创建静态库 创建一个.def文件,因为未提供该文件,并且也未使用u declspecdllexport/u declspecdlimport。请注意,此文件不包含允许链接器稍后指定DLL文件名的带库行。 如果项目未提供.def文件,有几种方法可以执行此操作: 3.1。从.h文件中获取符号。这可能很困难,因为有时您需要区分类型定义(例如typedef、enum、struct)和需要导出的实际函数和变量

echo "EXPORTS" > chebyshev.def
sed -n -e "s/^.* \**\(chebyshev_.*\) *(.*$/\1/p" chebyshev.h >> chebyshev.def
3.2。使用nm列出库文件中的符号,并筛选出所需的符号类型

echo "EXPORTS" > chebyshev.def
nm -f posix --defined-only -p libchebyshev.a | sed -n -e "s/^_*\([^ ]*\) T .*$/\1/p" >> chebyshev.def
将静态库链接到共享库中。 如果您有一个使用uu declspecdllexport/uu declspecdlimport的项目,事情会简单得多。您甚至可以让链接步骤使用-Wl,-output def,linker标志生成一个.def文件,如下所示:

gcc -shared -s -mwindows -o myproject.dll -Wl,--out-implib,myproject.dll.a -Wl,--output-def,myproject.def myproject.o

这个答案是基于我对C++的C.的经验,你真的应该使用“y-DEXSPECdLtReuts/OyDelpStCDLLimPur.< /P> < P>我相信我已经找到了一个在Windows上实现的机制,在

中描述了Linux的效果 这涉及

在最初的版本中,有这样一行:

gcc -o AddLib.dll obj/add.o obj/resource.o -shared -s -Wl,--subsystem,windows,--out-implib,libaddlib.a
我只是将其替换为以下两行:

dlltool -e obj/exports.o --dllname soname.dll -l libAddLib.a obj/resource.o obj/add.o
gcc -o AddLib.dll obj/resource.o obj/add.o obj/exports.o -shared -s -Wl,--subsystem,windows
实际上,关键似乎是使用dlltool和dllname一起创建导出文件。此导出文件与组成DLL主体的对象文件链接,并处理DLL与外部世界之间的接口。请注意,dlltool还同时创建导入库

现在我得到了预期的效果,我可以看到内部DLL名称不确定正确的术语是什么已经更改:

第一个证据:

>> dlltool.exe -I libAddLib.a
soname.dll
>> pexports.exe AddLib.dll
LIBRARY "soname.dll"
EXPORTS
Add
bar DATA
foo DATA
>> AddTest.exe
Error: the code execution cannot proceed because soname.dll was not found.
第二个证据:

>> dlltool.exe -I libAddLib.a
soname.dll
>> pexports.exe AddLib.dll
LIBRARY "soname.dll"
EXPORTS
Add
bar DATA
foo DATA
>> AddTest.exe
Error: the code execution cannot proceed because soname.dll was not found.
第三个证据:

>> dlltool.exe -I libAddLib.a
soname.dll
>> pexports.exe AddLib.dll
LIBRARY "soname.dll"
EXPORTS
Add
bar DATA
foo DATA
>> AddTest.exe
Error: the code execution cannot proceed because soname.dll was not found.

虽然达到了预期的效果,但这似乎仍然是一种解决办法。我的理解是,gcc选项-Wl,-soname应该实现完全相同的功能,但我可能错了。至少在Linux上是这样,但在Windows上可能会出现这种情况吗???

非常感谢您提供的所有详细信息和分享您的经验;-我能够毫无困难地复制您指示的所有步骤。通过您的方法,我可以看到两个关键点:1/DEF文件不包含带有库2的行/通过-Wl,-out implib选项,我可以使用与DLL名称不同的导入库名称。然而,我特别想要达到的效果有点不同-请参阅:为糟糕的格式道歉-我仍然不知道如何做我想做的事情-我不确定我是否确切了解您需要什么,但请注意,与Unix/Linux世界中的.so文件不同,在Unix/Linux世界中,LD_LIBRARY_PATH有助于定位共享库,Windows上的.dll文件需要与.exe文件位于同一位置或文件夹列表中
更具体地说:您的方法几乎实现了我想要的:dlltool-I libchebyshev.dll。a生成chebyshev-0.dll,这是链接导入库时作业的一半。然而,我想了解的是,如何将DLL内部名称设置为与DLL文件名不同的名称。你的方法不能解决这一半的工作。pexports.exe chebyshev-0.dll仍然生成库chebyshev-0。dll@DaveC内部名称必须与.dll名称匹配。它也是一个没有.dll扩展名的名称,以PE格式存储,用于.dll和.exe文件,以指定它们所依赖的共享库。我看不出这些有什么不同,或者你为什么想要这个。根据我上面的提示,您已经可以选择任何您想要的名称。您正在创建一个文件libAddLib.a-它实际上应该被称为libAddLib.dll.a,因为它是共享库的导入库-它引用soname.dll,而您的二进制文件实际上被称为AddLib.dll。这没有任何意义,因此AddTest.exe找不到正确的库是正常的。我不知道你为什么要做这样的事。我完全理解你为什么感到困惑。。。。当DLL文件名AddLib.DLL与PE结构soname.DLL中的DLL名称不匹配时,我不会对AddTest.exe没有找到正确的库感到惊讶-这正是我所期望的行为。我在最初的帖子中提出的观点是,当我使用-Wl、-soname、soname.dll来构建我的dll时,我希望AddTest.exe也会以同样的方式失败。但它仍然有效。。。。因此,本次讨论的标题是“-Wl,-soname”是否适用于MinGW?关于为什么构建一个文件名与PE结构(即soname)中的内部名称不匹配的DLL是有用的。有一个很好的讨论和大量的信息。这些链接描述了传统上在linux上使用但在Windows上不使用的机制。尽管如此,soname的概念存在于Windows上,因此我希望“-Wl,-soname”可以在MinGW上工作,但似乎不是。最后,“-Wl,-soname”可能对Windows没有影响,或者我的期望可能是错误的,但我上面提出的解决方案表明,使用dlltool和dllname可以实现相同的效果。AddTest.exe找不到正确的库这一事实表明soname被有效地设置在DLL的PE结构中。我一直认为-Wl,-soname,libname.DLL在MinGW上不起作用。我还认为,当您从源代码构建时,应该尽可能避免使用dlltool。我的建议是只使用dlltool为没有源代码的.dll文件生成.dll.a文件。我所有的发行版都是基于这些原则构建的,只是所有的东西都是从源代码开始构建的。