简体   繁体   中英

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

//API mathAPI.h, both in Dll.cpp and 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 is defined

#include "mathAPI.h"

double math::Pi = 3.14;

double math::Sum(double x, double y)
{
  return x + y;
}

// Test.cpp __APIBUILD not defined

#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;
}

Error 1 error LNK2001: unresolved external symbol "public: static double Math::Pi" (?Pi@Math@@2NA)

How do i get this to work?

The better solution to get your Pi value is to create a static method to init and return it, like the following in your 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;
}

This will prevent you of uninitialised value Pi, and will do what you want.

Please note that the best practice to initialize all static values/members is to initialize them in a function/method call.

Instead of exporting members one by one, export whole class . Also, I totally don't know how this code can work - you didn't provide definition for sum() (missing class scope operator) and that's what linker should complain about (instead of math::Sum() , you defined new, global 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);
};

Dll.cpp

#include "mathAPI.h"

double math::Pi = 3.14;

double math::Sum(double x, double y) //You missed 'math::' here before
{
  return x + y;
}

And that's it.


EDIT

You should still get an error, though. That's because you made a typo, that I haven't noticed (and you did not post the real code!). In your Dll.cpp , you wrote:

double math::Pi = 3.14;

Although you posted something different, I am sure, that your class is named Math , not math , because linker is trying to search for:

?Pi@Math@@2NA

So it is looking in class Math . This is the most probable guess. Though, I am pretty sure, that you did not post the real code, but hand-written snippet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM