我正在为使用C语言编写的语言解释器构建插件(扩展模块)系统。
在运行期间,程序使用LoadLibrary
来加载指定的DLL文件。这似乎可以使用基本DLL而不起作用,这些DLL不依赖于主程序中定义的功能。
但是,我正在尝试构建一个插件DLL,它确实依赖于主程序二进制文件中定义的功能。
为此,我interface.h
在主代码库中定义了一个标题,以供这些插件包括和使用。它定义了它们可能需要的功能的标题。该插件#include <interface.h>
在其标头中显示。
我像这样编译插件DLL:
gcc myplugin.c -shared -Wl,--subsystem,windows -D MYPLUGIN_EXPORTS -o myplugin.dll -I..\main_program_headers
然后,我得到以下类型的错误:
undefined reference to 'some function name'
这是否意味着我必须通过动态链接编译插件,使其与主程序中所依赖的实际二进制文件兼容?
如果是这样,这是否意味着.o
即使将它们链接到结果后,我仍需要保留主程序的各个文件.exe
?GCC可以直接链接到.o
文件吗?
无论如何,我真的希望能够LoadLibrary
在运行时修复加载时的函数引用。是不是
更新:
正如@tenfour的善意回答,DLL必须遵循正常的链接规则,并且在构建时需要解析函数引用。他/她建议使用一个系统,在该系统中,主机程序将传递给所需功能的插件指针。
这种方法确实有效,但我仍然想知道:
要允许插件直接从主应用程序调用函数,而在运行时没有任何特殊系统(除外LoadLibrary
),则需要哪种构建过程。
我想说的是,我的主要影响力来源是CPython解释器的扩展系统。在我看来,从它的文档可以看出,CPython扩展没有从主机解释器接收函数指针,并且仍然能够直接Py_*
从其解释函数。
知道如何做这样的事情吗?如何构建插件DLL以支持此功能?我需要链接什么以及如何链接?
由于您未发布interface.h
,所以我只能猜测您正在此处声明函数,例如:
int some_func();
如果插件代码尝试调用此方法,它将进行编译,但是链接器没有对此的引用。该函数的主体仅存在于主机应用程序中。
相反,如果要使用进行动态链接,则LoadLibrary
需要使用函数指针,例如:
typedef int (*some_func_ptr)(); // declare the fn pointer type
...
some_func_ptr some_func = x; // assign it after the host passes you x
...
some_func(); // now you can call it without linker issues.
而中提琴则使用了动态链接来创建插件系统。当然,您的界面设计将迫使此操作变得更加复杂,但是一旦您理解了该概念,这大部分只是工作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句