首先,我对 DLL 文件不是很有经验,如果这看起来像一个初学者问题,那么很抱歉。
在Linux上,您可以使用-rdynamic标志编译共享库,该标志使主进程中的符号加载到加载的共享库中,我想对DLL文件执行相同的操作,但我不知道如何,我已经已经使用以下命令创建了一个“.a”文件:
ar libvault.a bin_win/*.o
x86_64-w64-mingw32-dlltool --export-all-symbols main.exe -l libvault.a -D main.exe
// shared object structure:
struct SharedObject {
std::string name;
std::string typeName;
HINSTANCE handle;
Script *(*create)();
};
// script class
class Script {
public:
std::string objId;
std::string name;
virtual void Start(){};
virtual void Update(){};
};
sharedObj.handle = LoadLibrary(file.c_str());
sharedObj.create = (Script * (*)()) GetProcAddress(sharedObj.handle, "create_object");
sharedObj.name = dirEntry.path().filename().string();
DLL文件代码:
// NewScript.hpp
#pragma once
#include <api.hpp>
using namespace HyperAPI;
using namespace HyperAPI::Experimental;
#ifdef _WIN32
#ifdef BUILD_DLL
#define VAULT_API __declspec(dllexport)
#else
#define VAULT_API __declspec(dllimport)
#endif
#else
#define VAULT_API
#endif
extern "C" {
class NewScript : CppScripting::Script {
public:
NewScript() = default;
~NewScript() = default;
void Start() override;
void Update() override;
};
VAULT_API NewScript *create_object();
}
// NewScript.cpp
#include "NewScript.hpp"
NewScript *create_object() {
return new NewScript;
}
void NewScript::Start() {
Log log("start", LOG_INFO);
// this Log class escencially adds it into a vector variable that gets iterated in ImGui to be displayed
}
void NewScript::Update() {
Log log("update", LOG_WARNING);
}
// Somewhere in programming
Script *script = sharedObj.create();
script->Start(); // when this gets called, the logs variable doesn't get updated in the main process while it does on linux with ".so" files
编译DLL时,我链接libvault.a文件并添加-DBUILD_DLL
我已经阅读了 stackoverflow 中与此类似的所有问题,也在其他网站上进行了搜索,但没有任何效果
在搜索编译标志后我想出了如何做到这一点,这就是我找到它的方式:
我在所有想要从主进程导出到 DLL 文件的内容上添加
__declspec(dllexport)
,如下所示:
// header file
#ifdef _WIN32
#ifdef BUILD_DLL
#define DLL_API
#else
#define DLL_API __declspec(dllexport)
#endif
#else
#define DLL_API
#endif
DLL_API extern std::vector<GameObject*> gameObjects;
// cpp file
std::vector<GameObject*> gameObjects = {};
int main() {
// do stuf
}
编译命令:
x86_64-w64-mingw32-g++ -static -g -Og -std=c++20 -Wa,-mbig-obj bin_win/*.o -o main.exe -Wl,--export-all-symbols,--out-implib,libhost.a $(win_flags)
这将生成一个存档文件,您可以将其链接到 DLL 文件,以便它具有引用,除此之外所有变量和函数都将从主进程加载!