C++ 如何从 dll 导出静态类成员

C++ How to export a static class member from a dll?

本文关键字:静态类 成员 dll C++      更新时间:2023-10-16

//API mathAPI.h,在Dll.cpp和Test中都有.cpp

#ifdef __APIBUILD
#define __API __declspec(dllexport)
//#error __APIBUILD cannot be defined.
#else
#define __API __declspec(dllimport)
#endif
class math
{
 public:
   static __API double Pi;
   static __API double Sum(double x, double y);
};

定义 Dll.cpp __APIBUILD

#include "mathAPI.h"
double math::Pi = 3.14;
double math::Sum(double x, double y)
{
  return x + y;
}

测试.cpp __APIBUILD未定义

#include <iostream>
#pragma comment(lib, "dll.lib")
#include "mathAPI.h"
int main()
{
  std::cout << math::Pi; //linker error
  std::cout << math::Sum(5.5, 5.5); //works fine
  return 0;
}
错误

1 错误 LNK2001:未解析的外部符号"公共:静态双精度数学::P i"(?Pi@Math@@2NA)

我如何让它工作?

获取 Pi 值的更好解决方案是创建一个静态方法来初始化并返回它,就像 DLL 中的以下内容一样.cpp:

#include "mathAPI.h"
// math::getPi() is declared static in header file
double math::getPi()
{
    static double const Pi = 3.14;
    return Pi;
}
// math::Sum() is declared static in header file
double math::Sum(double x, double y)
{
  return x + y;
}

这将防止您未初始化的值 Pi,并会做您想要的。

请注意,初始化所有静态值/成员的最佳实践是在函数/方法调用中初始化它们。

不是逐个导出成员,而是导出整个类。另外,我完全不知道这段代码是如何工作的 - 您没有为 sum()(缺少类范围运算符)提供定义,这就是链接器应该抱怨的(而不是math::Sum(),您定义了新的全局sum())。

mathAPI.h

#ifdef __APIBUILD
#define __API __declspec(dllexport)
#else
#define __API __declspec(dllimport)
#endif
class __API math //Add __API to export whole class
{
 public:
   static double Pi;
   static double Sum(double x, double y);
};

哎呀.cpp

#include "mathAPI.h"
double math::Pi = 3.14;
double math::Sum(double x, double y) //You missed 'math::' here before
{
  return x + y;
}

仅此而已。


编辑

不过,您仍然应该收到错误。那是因为你打错了字,我没有注意到(而且你没有发布真正的代码!在你的Dll.cpp中,你写道:

double math::Pi = 3.14;

虽然你发布了一些不同的东西,但我敢肯定,你的类被命名为Math,而不是math,因为链接器正在尝试搜索:

?Pi@Math@@2NA

所以它在类Math中寻找.这是最可能的猜测。不过,我很确定,您没有发布真正的代码,而是手写的代码片段。