如何从使用相同头文件的主进程将符号和变量加载到 DLL 文件中? (基本上在 Linux 上是 -rdynamic)

问题描述 投票:0回答:1

首先,我对 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

但这些都不起作用!
我真的不知道该怎么办

加载DLL文件的代码:

// 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 中与此类似的所有问题,也在其他网站上进行了搜索,但没有任何效果

c++ dll dynamic-linking
1个回答
0
投票

在搜索编译标志后我想出了如何做到这一点,这就是我找到它的方式:
我在所有想要从主进程导出到 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 文件,以便它具有引用,除此之外所有变量和函数都将从主进程加载!

© www.soinside.com 2019 - 2024. All rights reserved.