我有一个加载主可执行文件。 dll
/ .so
的插件,它在Linux,但在Windows(的Visual Studio 2012)的作品就好了,它失败未定义引用错误。
插件使用类似功能的session->SendLine("bla")
其在主可执行文件中定义。 (包括类的在.h定义的会话ANS方法在插件,但在一个.cpp实际功能在主EXEC编译)。
TL;博士:“我需要在Windows连接忽略插件,未定义的引用在主可执行文件中定义”
什么是没有一个亿“使其正常工作”,在窗口,但保持兼容Linux的最好的方式#ifdef
的?
在Windows库的链接从它是如何在Linux上处理的处理完全不同。 从插件到主机可执行链接是简单的Linux,但没有这么多的Windows。
在Windows上链接到外部模块的传统方法是使用导入库,由的.lib文件中提供。 为了做到这样,你就需要为你的可执行文件,其中包括所有的导出函数,你的插件需要调用创建导入库。 我从来没有创建导入库的可执行文件。 通常情况下,你的DLL做到这一点。 我什至不知道它会为一个可执行的工作。
其他一些选项:
- 从可执行文件导出功能,并使用
GetProcAddress
在你的插件在运行时绑定到他们。 - 当你初始化插件,通过包含所有他们需要的功能的接口。
要调用DLL从一个可执行文件定义的函数,你必须使用__declspec(dllexport)的从可执行导出这些功能,就像你从DLL导出功能。
编译器将生成包含用于导出的函数存根可执行文件导入库。
链接与当你建立你的DLL这个引入库。
当使用MinGW的,这可以通过如下产生导入库的可执行文件来完成:
$ dlltool --export-all-symbols <program>.exe -l lib<program>.a -D <program>.exe
的-l
参数指定要创建的库的文件名,和-D
参数指定的库的其中dllname(和它是重要的,这是等于节目名称)。 要编译DLL,然后你会需要通过添加与导入库链接-l<program>
的连接标志。
如果要限制输出符号,你可以首先生成一个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
注:dlltool的名称可能因MinGW的环境变化(即i686-w64-mingw32-dlltool
在Fedora上进行编译十字i686的窗户)。
我有同样的问题-一个专有的应用程序,a.exe的 ,我想建立一个插件,p.dll。
后一个建议:
$ dlltool --export-all-symbols a.exe -z a.defs
dlltool: a.exe: no symbols
但有附带A.EXE一个A.LIB文件。 同样,没有[有用]出口:
$ 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
[见还构建DLL与使用库文件(.a)中一个gcc从导入库转化(.LIB)
最终,一个MinGW的邮件列表上找到一个提示, 纳米是我的解决方案:
$ echo EXPORTS >a.def
$ nm -p a.lib |egrep 'T _' |sed 's/0* T _//' >>a.def
一旦你有一个这样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