__declspec(dllimport) 和外部 (OBS)
__declspec(dllimport) and extern (OBS)
我正在浏览 OBS 源代码以了解他们是如何制作插件系统的。我被困在一个我无法复制的部分,而且我在任何地方都找不到答案。
为了与OBS 加载的插件(dll) 共享函数,有一个指向APIInterface
的指针。这个指针被命名为 API
所以我从现在开始就这样称呼它。此变量在 OBSApi\APIInterface.h
中声明,声明为:BASE_EXPORT extern APIInterface *API;
其中 BASE_EXPORT
在 OBSApi\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
,就可以使用导出的您自己程序中的函数和变量。
我正在浏览 OBS 源代码以了解他们是如何制作插件系统的。我被困在一个我无法复制的部分,而且我在任何地方都找不到答案。
为了与OBS 加载的插件(dll) 共享函数,有一个指向APIInterface
的指针。这个指针被命名为 API
所以我从现在开始就这样称呼它。此变量在 OBSApi\APIInterface.h
中声明,声明为:BASE_EXPORT extern APIInterface *API;
其中 BASE_EXPORT
在 OBSApi\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
,就可以使用导出的您自己程序中的函数和变量。