A little background; I'm writing a plugin system for a game engine that will have the main engine code running from the exe (provided by a library, say engine.lib). I want to be able to export some global variables from engine.lib into a plugin dll that's loaded at run-time.
So for example;
engine.lib: Has a variable called g_foobar that is initialised at some point by the exe that statically links to engine.lib
plugin.dll: This also statically links to engine.lib as I want to be able to manipulate g_foobar using the various classes within engine.lib
Obviously when the plugin loads it has it's own instance of g_foobar which isn't initialised to the same as the g_foobar within the exe.
I want to (with a bit of dllexport/dllimport magic) make the dynamic linker link up the two symbols so that the g_foobar within the dll points to the same memory as the one in the exe.
Some code I've had a play with (3 VS projects, 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)
{
}
Even after compiling the exe/lib/dll in various ways (altering the API define), I can't get the output to print '100', it will always print '0' because I'm statically linking with the engine.lib.
I'm wondering if anyone knows how to get this working because there's surely something obvious I'm doing wrong.
NOTE: Removing the use of the static library isn't really an option due to the way the rest of the codebase works.
Cheers.
答案 0 :(得分:0)
因此,经过长时间的观察和与工作中的一些人交谈,我们设法放弃了对静态库的需求,因为我认为不可能这样做。
因此,基于上面的示例代码,enginelib成为DLL,头API块变为:
#if defined(__ISADLL__)
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif
并且plugindll和exe都链接到由enginelib dll构建生成的.lib。