Немного фона; Я пишу систему плагинов для игрового движка, в которой будет работать основной код двигателя, выполняемый exe (предоставляется библиотекой, например engine.lib). Я хочу иметь возможность экспортировать некоторые глобальные переменные из engine.lib в dll плагина, который загружается во время выполнения.Импорт переменных в DLL
Так, например;
engine.lib: Имеет переменную под названием g_foobar, который инициализируется в какой-то момент по ехе, что статически ссылки на engine.lib
plugin.dll: Это также статически ссылки на engine.lib, как Я хочу, чтобы иметь возможность манипулировать g_foobar, используя различные классы в engine.lib
Очевидно, когда плагин загружает его имеет собственный экземпляр g_foobar, не инициированные к тому же, как g_foobar в exe.
Я хочу (с небольшим количеством dllexport/магии DllImport) сделать ссылку динамического компоновщика до двух символов, так что g_foobar внутри DLL указывает на ту же память, что и один в ехе.
код, который я имел игру с (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/длл различными способами (изменение API определения), я не могу получить вывод на печать '100', он всегда будет печатать '0', потому что я статически связываюсь с engine.lib.
Мне интересно, знает ли кто-нибудь, как это работает, потому что есть что-то очевидное, что я делаю неправильно.
ПРИМЕЧАНИЕ. Удаление использования статической библиотеки на самом деле не является вариантом из-за того, как работает остальная часть кодовой базы.
Cheers.
У вашего EXE есть своя копия g_foobar, связанная с enginelib. Без обмена. Необходимость использования LoadLibrary() делает его недружественным, вам нужно экспортировать функцию SetFooBar(), чтобы EXE мог установить указатель, используемый DLL. –
Да, я понимаю, что есть две копии переменной, но я ищу для динамического компоновщика, чтобы g_foobar в dll указывал на то же пространство памяти, что и g_foobar в хосте exe, поэтому я могу получить доступ к любому это приложение для хоста. – Olly
Ну, конечно, было бы проще, если бы вы дали динамически ссылку. Но вы этого не делаете и используете LoadLibrary(). Затем вам нужно связать себя с GetProcAddress(), вы уже знаете, как это сделать. Вы не можете иметь это в обоих направлениях, такова цена плагинов. –