|
|
1
36
可以做到… 我们在这里的方法是使用链接器的/def选项传递 "module definition file" 包含我们的出口清单。我从你的问题中看出你知道这些文件。但是,我们不是用手做的。导出列表本身由 dumpbin /linkermember命令,并通过一个简单的脚本将输出操作为模块定义文件的格式。 安装是一项非常繁重的工作,但它允许我们编译在Windows上不使用dllexport声明为UNIX创建的代码。 |
|
|
2
29
简短回答您可以在新版本的cmake(任何版本的cmake-3.3.20150721-g9cd2f-win32-x86.exe或更高版本)的帮助下完成此操作。 目前它在dev分支中。 稍后,该功能将添加到CMAKE-3.4的发布版本中。 链接到cmake dev: 链接到描述技术的文章: Create dlls on Windows without declspec() using new CMake export all feature 链接到示例项目: cmake_windows_export_all_symbols 长回答警告: 下面的所有信息都与MSVC编译器或Visual Studio有关。 如果在Linux上使用其他编译器,如GCC或Windows上使用Mingw GCC编译器,则不会因未导出符号而出现链接错误,因为GCC编译器默认导出动态库(dll)中的所有符号,而不是MSVC或Intel Windows编译器。 在Windows中,必须从DLL显式导出符号。 有关此问题的详细信息由以下链接提供: HowTo: Export C++ classes from a DLL 因此,如果要使用msvc(Visual Studio编译器)从dll中导出所有符号,则有两个选项:
1。在类/函数的定义中使用关键字declspec(dllexport) 1.1。向要使用的类或方法中添加“u declspec(dllexport)/”declspec(dllimport)”宏。因此,如果要导出所有类,则应将此宏添加到所有类中 链接提供了有关此的详细信息: Exporting from a DLL Using __declspec(dllexport) 使用示例(用真实项目名称替换“项目”):
然后将“projectapi”添加到所有类中。 仅当需要从dll导出/导入符号时才定义“useprojectlibrary”。 为dll定义“projectlibrary_exports”。 类导出示例:
函数导出示例:
警告: 不要忘记包含“projectexport.h”文件。 1.2。导出为C函数。 如果你用C++编译器编写C代码,你可以在函数前面加上一个“C”来消除名字的错误。 有关C++名称的更多信息由链接提供: 使用示例:
链接提供了有关此的详细信息: Exporting C++ Functions for Use in C-Language Executables 2。创建模块定义(.def)文件,并在生成dll时使用.def文件 链接提供了有关此的详细信息: Exporting from a DLL Using DEF Files 接下来,我描述了三种关于如何创建.def文件的方法。 2.1。导出C函数 在这种情况下,您可以简单地手工在.def文件中添加函数声明。 使用示例:
.def文件示例(uu cdecl命名约定):
2.2。从静态库导出符号 我尝试了“user72260”建议的方法。 他说:
我使用了这种方法,但是总是创建两个构建(一个是静态的,另一个是动态库)并不是很方便。但是,我不得不承认,这种方法确实有效。 2.3。从.obj文件或借助cmake导出符号 2.3.1使用cmake 重要提示: 您不需要将宏导出到类或函数! 重要提示: 您不能使用/gl( Whole Program Optimization )使用此方法时!
使用示例: 根文件夹 cmakelists.txt(根文件夹)
main.cpp(根文件夹)
foo文件夹(根文件夹/foo文件夹) cmakelists.txt(foo文件夹)
foo.h(foo文件夹)
foo.cpp(foo文件夹)
再次链接到示例项目: cmake使用与“2.2”不同的。从静态库中导出符号“方法。 它执行以下操作: 1)在build目录中创建包含.obj文件信息的“objects.txt”文件,该文件在dll中使用。 2)编译dll,即创建.obj文件。 3)根据“objects.txt”文件信息,从.obj文件中提取所有符号。 使用示例:
链接提供了有关此的详细信息: 4)解析从.obj文件信息中提取的内容。 在我看来,我将使用调用对流,例如“uu cdecl/uuu fastcall”、“sectx/undef”符号字段(第三列)、“external/static”符号字段(第五列)、“?“?”用于分析.obj文件的信息。 我不知道cmake如何准确地解析.obj文件。 但是,cmake是开放源码的,因此您可以了解它是否对您感兴趣。 链接到cmake项目: 5)将所有导出的符号放在.def文件中。 6)使用.def创建的文件链接DLL。 步骤4)-5),即在链接和使用.def文件之前,在“预链接事件”的帮助下解析.obj文件并创建.def文件。 当“预链接事件”触发时,您可以调用任何您想要的程序。 因此,在“cmake usage”“pre-link event”的情况下,使用以下信息调用cmake,这些信息包括放置.def文件的位置、“objects.txt”文件的位置以及参数“-e_uu create_def”。 您可以通过使用“set(cmake-windows-export-all-u-symbols on)”创建cmake-visusal studio项目来检查此信息,然后检查dll的“.vcxproj”项目文件。 如果您试图编译一个没有“set(cmake_windows_export_all_symbols on)”或“set(cmake_windows_export_all_symbols off)”的项目,您将得到链接错误,因为符号不是从dll导出的。 链接提供了有关此的详细信息: Understanding Custom Build Steps and Build Events 2.3.2.不使用cmake 您可以创建一个小程序来解析.obj文件,而不需要使用cmake。霍维尔,我不得不承认,cmake是非常有用的程序,特别是对于跨平台开发。 |
|
|
3
8
我编写了一个小程序来解析.lib文件上“dumpbin/linkermember”的输出。我有超过8000个函数引用要从一个DLL导出。 在dll上执行此操作的问题是,必须在不使用导出定义的情况下链接一次dll才能创建.lib文件,然后生成.def,这意味着您现在必须再次将dll与.def文件重新链接,以实际导出引用。 使用静态库更容易。将所有源编译成静态libs,运行dumbin,用您的小程序生成一个.def,然后在导出名称可用的情况下将libs链接到一个dll中。 不幸的是,我的公司不允许我告诉你消息来源。所涉及的工作是识别在您的def文件中不需要转储输出中的哪些“公共符号”。您必须丢弃大量的引用、空的导入描述符、空的thunk数据、空的imp*等。 |
|
|
4
2
感谢@maks detailed answer . 下面是我在预链接事件中用来从obj生成def文件的示例。我希望它能对某人有所帮助。
基本上,我只取了一个对象(mdb.obj)和grepped mdb_x函数。然后对输出进行解析,以便只保留名称,同时考虑缩进的空间量(一个在拆分成标记后,另一个在Echo中)。但我不知道这是否重要)。 不过,现实世界的剧本可能会更复杂一些。 |
|
5
0
这是一个迟交的答案,但它在第(2)节中提供了Maks答案的详细信息。它还避免脚本,并使用C++程序调用
最后,下面的步骤假设您在Visual Studio中工作
Developer Prompt
,这是一个Windows终端,
以下使用说明:
还要注意,尽管您正在从dll导出所有内容,但客户端仍然必须使用
首先,获取对象并创建静态存档:
第二,运行
第三,运行
第四,构建DLL:
当
还有:
把它粘在一起就是nmake makefile的样子。它是A的一部分 real Nmake file :
这是的源代码
|
|
|
6
-3
不,您需要一个宏来解析为
|
|
|
Albert Laure · 在SSRS中的不同数据集中添加值字段 13 年前 |
|
|
Edward Newgate · 正确的Json反序列化 14 年前 |
|
|
DiggDev · visualstudio2005 ctrl+f不工作 14 年前 |