如何使用公开导出的全局 DLL 变量?

Posted

技术标签:

【中文标题】如何使用公开导出的全局 DLL 变量?【英文标题】:How to use publically exported global DLL variables? 【发布时间】:2016-05-31 04:39:03 【问题描述】:

假设我有 2 个简单的类 AC,我还有指向 AC 的指针形式的全局外部变量。代码:

//global.h
#pragma once
#include "A.h"
#include "C.h"
struct A;
struct C;
extern A* external_a;
extern C* external_c;
/////////////////////////////////////////
//A.h
#pragma once
struct A 
    void get();
;
/////////////////////////////////////////    
//A.cpp
#include "A.h"
void A::get() 
/////////////////////////////////////////
//C.h
#pragma once
# include "global.h"
struct C 
    void doit();
;
/////////////////////////////////////////   
//C.cpp
# include "C.h"
void C::doit()  external_a->get(); 
/////////////////////////////////////////

我只列出了 DLL 代码。关键是 DLL 用户从(声明)他的 EXE 代码中提供 main.cpp 全局变量供我的 DLL 代码使用。所以用户不在同一个项目中,而我想在我的 DLL 项目中的多个文件中使用该外部变量。

我从这段代码中得到两个关于unresolved external symbol "struct A * external_a"的错误

我尝试在类定义中和external 关键字之后写__declspec(dllexport)。它无助于修复错误。所以我想知道该怎么做才能编译这样的项目?

【问题讨论】:

“A.h”中存在什么。你在哪里定义了A* external_a,应该先声明它与extern关键字一起使用。 我看不到 external_aexternal_c 是在哪里定义的。 您是否尝试过 DLL 中明显的 extern __declspec(dllimport) A* external_a;__declspec(dllexport) A* external_a;? (“显而易见”是指“如果您已经知道如何导出函数,则显而易见) 是的,我试过了——同样的错误。 external_a 和 external_c 由 DLL 用户定义。 use static class variable/function across dlls的可能重复 【参考方案1】:

错误信息很清楚,与 DLL 或 DLL 导入/导出无关。您已经声明了“外部链接” extern A* external_a;,但是外部链接是什么?

在您的一个 *.cpp 文件(通常是包含主入口点的文件)中应该有一个全局变量的声明。如果您使用的是指针,那么您还必须分配它。例如

文件"main.cpp"

#include "a.h"

//Initialize pointer here:
MyStructA* global_a;
int main()

    //Allocate data here
    //(unless this is a DLL project and you are passing a variable)
    global_a = new MyStructA;
    foo();
    return 0;

(我把变量名改成了global_a,这样更有意义)

如果您想在同一项目的另一个文件中使用global_a,请使用extern MyStructA* global_a;。例如,在"otherfile.cpp"

#include "a.h"

extern MyStructA* global_a;
foo();
...


如果您有 EXE 项目和单独的 DLL 项目,则使用 dllexport/dllimport 访问 DLL 中的函数。在EXE项目中声明数据,然后使用函数传递数据。 extern 在这种情况下不相关。例如:

在 DLL 项目中使用dllexport

MyStructA *global_a;

__declspec(dllexport) void foo(MyStructA *p)

    global_a = p;

在EXE项目中使用dllimport

__declspec(dllimport) void foo(MyStructA *p);

MyStructA A;
foo(&A);

【讨论】:

我只列出了 DLL 代码。关键是 DLL 用户从他的说 main.cpp 中提供全局变量供我的代码使用。所以用户不在同一个项目中。虽然我想在我的 DLL 项目中的多个文件中使用该外部变量 我已经解释了他们两个。你应该单独弄清楚。为extern编写一个简单的测试项目,为DLL编写另一个测试项目,然后根据需要将它们放在一起。 这不是让他们分开。它是关于将全局变量的实例从外部 EXE 提供到 Dll 中,w2hile 在 exe 中使用该全局变量

以上是关于如何使用公开导出的全局 DLL 变量?的主要内容,如果未能解决你的问题,请参考以下文章

当一个 DLL 被多次链接时,导出的全局变量会发生啥?

Windows中的库编程

如何导出类模板静态变量 DLL windows

从 C++ dll 导出一个类?

QLibrary Visual C++ 全局变量

调试实战 —— dll 加载失败之全局变量初始化篇