[英].dll Plugin that uses functions defined in the main executable
I have a Main executable that loads . 我有一个主要的可执行文件加载。 dll
/ .so
Plugins, which works just fine in Linux but on windows(Visual Studio 2012), it fails with undefined reference errors. dll
/ .so
插件,在Linux上运行得很好但在Windows上运行(Visual Studio 2012),它因未定义的引用错误而失败。
The plugin uses functions like session->SendLine("bla")
which are defined in the Main executable. 该插件使用session->SendLine("bla")
等函数,这些函数在Main可执行文件中定义。 (class of session ans methods defined in a .h included in the plugin, but the actual function in a .cpp compiled in main exec). (在插件中包含的.h中定义的会话和方法类,但是在main exec中编译的.cpp中的实际函数)。
tl;dr: "I need the windows linker to ignore undefined references in plugins, defined in the main executable" tl; dr:“我需要Windows链接器来忽略插件中未定义的引用,在主可执行文件中定义”
What is the best way to "make it work" in windows but keep it compatible with Linux without a million #ifdef
's? 在Windows中“使其工作”的最佳方法是什么,但在没有百万#ifdef
的情况下保持与Linux兼容?
Linking of libraries on Windows is handled completely differently from how it is handled on Linux. Windows上的库链接处理方式与在Linux上处理它的方式完全不同。 Linking from plugin to host executable is simple on Linux, but not so much on Windows. 从插件到主机可执行文件的链接在Linux上很简单,但在Windows上却没有那么多。
On Windows the traditional way to link to an external module is to use an import library, provided by a .lib file. 在Windows上,链接到外部模块的传统方法是使用由.lib文件提供的导入库。 In order to do it that way, you would need to create an import library for your executable file which includes all the exported functions that your plugins need to call. 为了这样做,您需要为可执行文件创建一个导入库,其中包含插件需要调用的所有导出函数。 I've never created an import library for an executable. 我从来没有为可执行文件创建导入库。 Normally you do it for a DLL. 通常你是为DLL做的。 I'm not even sure it will work for an executable. 我甚至不确定它是否适用于可执行文件。
Some other options: 其他一些选择:
GetProcAddress
in your plugin to bind to them at runtime. 从可执行文件导出函数,并在插件中使用GetProcAddress
在运行时绑定到它们。 To call functions defined in an executable from DLL, you have to export those functions from an executable using __declspec(dllexport), just as you export functions from DLL. 要从DLL调用可执行文件中定义的函数,必须使用__declspec(dllexport)从可执行文件中导出这些函数,就像从DLL导出函数一样。
The compiler will generate an import library for the executable that includes stubs for the exported functions. 编译器将为可执行文件生成一个导入库,其中包含导出函数的存根。
Link with this import library when you build your DLL. 在构建DLL时链接此导入库。
When using mingw, this can be done by generating an import library for the executable as follows: 使用mingw时,可以通过为可执行文件生成导入库来完成此操作,如下所示:
$ dlltool --export-all-symbols <program>.exe -l lib<program>.a -D <program>.exe
The -l
argument specifies the filename of the library to be created, and the -D
argument specifies the dllname of the library (and it is important that this is equal to the program name). -l
参数指定要创建的库的文件名, -D
参数指定库的dllname(重要的是它等于程序名称)。 To compile the dll, you will then need to link against the import library by adding -l<program>
to the linker flags. 要编译dll,您需要通过将-l<program>
添加到链接器标志来链接导入库。
If you want to limit the exported symbols, you can first generate a defs file, edit it, and then generate the import library from the defs file: 如果要限制导出的符号,可以先生成defs文件,编辑它,然后从defs文件生成导入库:
$ dlltool --export-all-symbols <program>.exe -z <program>.defs
$ vi <program>.defs # Edit the list of exported symbols
$ dlltool -d <program>.defs -l lib<program>.a -D <program>.exe
Note: The name of dlltool may vary depending on the mingw environment (ie i686-w64-mingw32-dlltool
on Fedora for cross-compiling to i686 windows). 注意: dlltool的名称可能因mingw环境而异(即Fedora上的i686-w64-mingw32-dlltool
用于交叉编译到i686窗口)。
I had the same problem - for a proprietary app, a.exe , I wanted to build a plugin, p.dll . 我有同样的问题 - 对于专有应用程序, a.exe ,我想构建一个插件, p.dll 。
One post suggested: 一篇帖子建议:
$ dlltool --export-all-symbols a.exe -z a.defs
dlltool: a.exe: no symbols
But there was an a.lib file included with a.exe . 但有附带A.EXE一个A.LIB文件。 Again, no [useful] EXPORTS: 再次,没有[有用]出口:
$ dlltool --export-all-symbols a.lib -z a.defs
$ cat a.defs
; dlltool --export-all-symbols -z a.defs q.lib
EXPORTS
_NULL_IMPORT_DESCRIPTOR @ 1 DATA
_IMPORT_DESCRIPTOR_a @ 2 DATA
[see also Building a dll with a gcc using a library file (.a) converted from import library (.lib) [另请参阅使用从导入库(.lib)转换的库文件(.a)使用gcc构建dll
Eventually, finding a hint on a MinGW mailing list, nm was the solution for me: 最后,在MinGW邮件列表上找到提示, nm对我来说是解决方案:
$ echo EXPORTS >a.def
$ nm -p a.lib |egrep 'T _' |sed 's/0* T _//' >>a.def
Once you have a this .def file, it's easy: 一旦你有这个.def文件,它很容易:
$ #generate liba.a that has the callbacks for the symbols in *a.exe* (what a.lib has, too)
$ dlltool -v -l liba.a -d a.def
$ #build my plugin, linking to liba.a
$ gcc -shared p.c -L. -la -o p.dll
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.