从exe和dll访问静态lib中的extern变量

时间:2018-09-28 12:20:37

标签: c++

在我的项目中,我有一个exe,一个dll和一个静态lib。

依赖关系如下:

 exe -> dll -> lib
  |             ^
  |_____________|

exe依赖于dll和lib,而dll依赖于lib。

libfile.h

struct A {
   A(int i) : x(i) {}
   int x;
};
extern A* ptr;

libfile.cpp中,我有A* ptr = nullptr;

exefile.cpp

#include "libfile.h"
__declspec(dllimport) void foo();
int main() {
  ptr = new A(10);
  foo();
  delete ptr;
}

dllfile.cpp

 #include "libfile.h"
__declspec(dllexport) void foo();
__declspec(dllexport) void foo() { 
    int a = ptr->x; //error, ptr is nullptr 
}

如何在不将其作为函数参数传递的情况下从exe和dll访问lib中的A* ptr?我尝试在dll中使用接口函数将ptr返回给exe,但错误仍然存​​在。

2 个答案:

答案 0 :(得分:2)

如果一个exe,DLL或多个DLL(或Linux)使用相同的静态库,则它们各自会获得该库的副本。这意味着所有全局变量和静态变量都是单独的,甚至可能是静态库的不同版本(例如,如果您更改了静态库,则重新编译了exe而未重新编译DLL)。

如果要共享该库中的资源,则需要通过其他方式进行。例如,您可以:

  • 将静态库放入另一个DLL
  • 静态链接所有内容
  • 避免共享静态库中的全局变量,并将所有内容作为函数参数传递

答案 1 :(得分:1)

ptr的dll和exe具有不同的内存位置。我在这里假设您已在exe中声明了ptr,否则您将收到链接错误(我正在查看此行ptr = new A(10);)。更改一个不会影响另一个。

要“很好”地解决这个问题,是从dll中导出ptr的getter和setter函数(就像对foo所做的一样):

__declspec(dllexport) A* getPtr() { return ptr; }
__declspec(dllexport) void setPtr(A* new_value) { ptr = new_value; }

在exe文件中,只需将getPtr/setPtr声明为dllimport,然后使用它们与ptr进行交互即可。