将变量导入 DLL
Importing variables into a DLL
一点背景;我正在为一个游戏引擎编写一个插件系统,它将具有来自 exe 的主引擎代码 运行ning(由库提供,比如 engine.lib)。我希望能够将一些全局变量从 engine.lib 导出到在 运行 时加载的插件 dll 中。
例如;
engine.lib:有一个名为 g_foobar 的变量,该变量在某个时候由静态 link 的 exe 初始化为 engine.lib
plugin.dll:这也静态 links 到 engine.lib 因为我希望能够使用 g_foobar engine.lib
中的各种 类
显然,当插件加载时,它有自己的 g_foobar 实例,它未初始化为与 [=76= 相同的实例] 在 exe.
我想(用一点 dllexport/dllimport 魔法)使动态 linker link 向上两个符号,以便 g_foobar在dll中指向与exe中相同的内存。
我玩过的一些代码(3 个 VS 项目、exe、enginelib、plugindll):
Header.h
#pragma once
#if !defined(__ISALIB__)
#if defined(__ISADLL__)
#define API __declspec(dllimport)
#else
#define API __declspec(dllexport)
#endif
#else
#define API
#endif
class API CFoobar
{
public:
CFoobar(int i);
int m_iDave;
};
extern API CFoobar* g_foobar;
EXE.cpp
#include <windows.h>
#include "Header.h"
typedef void (*FooFN)();
CFoobar s_Foo(100);
int main(int argc, char** argv)
{
g_foobar = &s_Foo;
HMODULE h = LoadLibraryA("plugin.dll");
FooFN func = (FooFN)GetProcAddress(h, "Foobar");
func();
return 0;
}
plugindll.cpp
#include "Header.h"
extern "C" __declspec(dllexport) void Foobar()
{
printf("VALUE: %d\n", g_foobar->m_iDave);
}
enginelib.cpp
#include "Header.h"
CFoobar* g_foobar = NULL;
CFoobar::CFoobar(int i)
:m_iDave(i)
{
}
即使在以各种方式编译 exe/lib/dll 之后(更改 API 定义),我也无法让输出打印“100”,它总是打印“0”,因为我与 engine.lib.
静态 linking
我想知道是否有人知道如何让它工作,因为肯定有一些明显的我做错了。
注意:由于其余代码库的工作方式,删除静态库的使用并不是一个真正的选择。
干杯。
因此,经过长时间的研究并与工作中的一些人交谈后,我们设法放弃了对静态库的需求,因为我认为这是不可能的。
所以根据我上面的示例代码,enginelib 变成了一个 DLL,头文件 API 块变成:
#if defined(__ISADLL__)
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif
并且 plugindll 和 exe 都 link 到由 enginelib dll 构建生成的 .lib。
一点背景;我正在为一个游戏引擎编写一个插件系统,它将具有来自 exe 的主引擎代码 运行ning(由库提供,比如 engine.lib)。我希望能够将一些全局变量从 engine.lib 导出到在 运行 时加载的插件 dll 中。
例如;
engine.lib:有一个名为 g_foobar 的变量,该变量在某个时候由静态 link 的 exe 初始化为 engine.lib
plugin.dll:这也静态 links 到 engine.lib 因为我希望能够使用 g_foobar engine.lib
中的各种 类显然,当插件加载时,它有自己的 g_foobar 实例,它未初始化为与 [=76= 相同的实例] 在 exe.
我想(用一点 dllexport/dllimport 魔法)使动态 linker link 向上两个符号,以便 g_foobar在dll中指向与exe中相同的内存。
我玩过的一些代码(3 个 VS 项目、exe、enginelib、plugindll):
Header.h
#pragma once
#if !defined(__ISALIB__)
#if defined(__ISADLL__)
#define API __declspec(dllimport)
#else
#define API __declspec(dllexport)
#endif
#else
#define API
#endif
class API CFoobar
{
public:
CFoobar(int i);
int m_iDave;
};
extern API CFoobar* g_foobar;
EXE.cpp
#include <windows.h>
#include "Header.h"
typedef void (*FooFN)();
CFoobar s_Foo(100);
int main(int argc, char** argv)
{
g_foobar = &s_Foo;
HMODULE h = LoadLibraryA("plugin.dll");
FooFN func = (FooFN)GetProcAddress(h, "Foobar");
func();
return 0;
}
plugindll.cpp
#include "Header.h"
extern "C" __declspec(dllexport) void Foobar()
{
printf("VALUE: %d\n", g_foobar->m_iDave);
}
enginelib.cpp
#include "Header.h"
CFoobar* g_foobar = NULL;
CFoobar::CFoobar(int i)
:m_iDave(i)
{
}
即使在以各种方式编译 exe/lib/dll 之后(更改 API 定义),我也无法让输出打印“100”,它总是打印“0”,因为我与 engine.lib.
静态 linking我想知道是否有人知道如何让它工作,因为肯定有一些明显的我做错了。
注意:由于其余代码库的工作方式,删除静态库的使用并不是一个真正的选择。
干杯。
因此,经过长时间的研究并与工作中的一些人交谈后,我们设法放弃了对静态库的需求,因为我认为这是不可能的。
所以根据我上面的示例代码,enginelib 变成了一个 DLL,头文件 API 块变成:
#if defined(__ISADLL__)
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif
并且 plugindll 和 exe 都 link 到由 enginelib dll 构建生成的 .lib。