__declspec(dllimport) 和外部 (OBS)

__declspec(dllimport) and extern (OBS)

我正在浏览 OBS 源代码以了解他们是如何制作插件系统的。我被困在一个我无法复制的部分,而且我在任何地方都找不到答案。

为了与OBS 加载的插件(dll) 共享函数,有一个指向APIInterface 的指针。这个指针被命名为 API 所以我从现在开始就这样称呼它。此变量在 OBSApi\APIInterface.h 中声明,声明为:BASE_EXPORT extern APIInterface *API; 其中 BASE_EXPORTOBSApi\Utility\XT_Windows.h 中定义

#if defined(NO_IMPORT)
    #define BASE_EXPORT
#elif !defined(BASE_EXPORTING)
    #define BASE_EXPORT     __declspec(dllimport)
#else
    #define BASE_EXPORT     __declspec(dllexport)
#endif

最后,在 OBS 对象的构造函数中(在主程序中)它用 API = CreateOBSApiInterface();.

初始化 API

但是,如果有一个我只声明而不初始化的变量,我将无法编译。所以,我想知道我错过了什么,这个 API 变量如何在插件之间共享?

感谢您的回答。

插件在这种情况下所做的是使用一个全局变量,该变量是使用 __declspec(dllexport) 从插件导出到您的程序中的。
在您的程序中,它是使用 __declspec(dllimport).

导入的

变量本身是在插件中定义的,extern 告诉你的程序在当前编译单元中找不到声明,所以当 linker 关闭时会找到它去寻找它。

一个看起来如何的小例子如下:

plugin.h

/* define the int* as an exported external. */
BASE_EXPORT extern int* exportedInt;

plugin.c

#define BASE_EXPORTING /* so the macro shown will export. */
#include "plugin.h"

/* actually define the int* so it exists for the linker to find. */
int* exportedInt = NULL;

your_program.c

#include "plugin.h"

/* use the int* in your program, the linker will find it in plugin.cpp. */
exportedInt = CreateIntPointerFunction();

然后可以将插件编译为静态 (.lib) 或动态(.lib.dll)库,然后您可以 link 使用您的代码.

对于动态库,您可以选择:

  • 在运行时动态加载它,不需要 .lib 但您需要手动查找值和入口点。
  • Link 它在编译时使用 .lib.dll 组合,它将自动告诉程序在哪里可以找到所有入口点和值。

只要在编译单元中包含头文件,并告诉 linker 在不进行运行时加载时在哪里可以找到 .lib,就可以使用导出的您自己程序中的函数和变量。