代码之家  ›  专栏  ›  技术社区  ›  Aviv Cohn

在构建将使用LoadLibrary加载的DLL时,我是否需要与依赖的二进制文件链接,或者包含的头文件是否足够?

  •  0
  • Aviv Cohn  · 技术社区  · 6 年前

    我正在为我用C编写的语言解释器构建一个插件(扩展模块)系统。

    在运行时,程序使用 LoadLibrary 以加载指定的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'
    
    1. 这是否意味着我必须编译插件,并将其动态链接到主程序中所依赖的实际二进制文件?

    2. 如果是,这是否意味着我需要保留个人 .o 主程序的文件,即使在将其链接到结果之后 .exe ?可以直接针对 。o 文件?

    3. 不管怎样,我真的希望 加载 负责修复运行时加载的函数引用。不是吗?

    更新时间:

    正如@tenfour善意地回答的那样,DLL必须遵循正常的链接规则,并且需要在构建时解析函数引用。他/她建议使用一种系统,在该系统中,宿主程序将传递到插件指针中,以获得所需的功能。

    这种方法确实有效,但我仍然想知道:

    需要什么样的构建过程才能允许插件直接从主应用程序调用函数,而在运行时不需要任何特殊系统(除了 加载 )。

    我想说的是,我在这里的主要影响力来源是CPython口译员的扩展系统。在我看来 its documentation CPython扩展没有从主机解释器接收函数指针,仍然能够直接调用 Py_* 它的功能。

    你知道怎么做这样的事吗?如何构建插件DLL来支持这一点?我需要链接什么以及如何链接?

    0 回复  |  直到 6 年前
        1
  •  0
  •   tenfour    6 年前

    因为你没有发帖 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.
    

    viola使用动态链接创建插件系统。当然,界面的设计将迫使这变得更加复杂,但一旦你理解了这个概念,这大部分只是劳动。