简体   繁体   中英

Making Visual C++ DLL from C++ class

I have the following C++ code to make dll (Visual Studio 2010).

class Shape {
public:
  Shape() {
    nshapes++;
  }
  virtual ~Shape() {
    nshapes--;
  };
  double  x, y;   
  void    move(double dx, double dy);
  virtual double area(void) = 0;
  virtual double perimeter(void) = 0;
  static  int nshapes;
};

class __declspec(dllexport) Circle : public Shape {
private:
  double radius;
public:
  Circle(double r) : radius(r) { };
  virtual double area(void);
  virtual double perimeter(void);
};

class __declspec(dllexport) Square : public Shape {
private:
  double width;
public:
  Square(double w) : width(w) { };
  virtual double area(void);
  virtual double perimeter(void);
};

I have the __declspec,

class __declspec(dllexport) Circle

I could build a dll with the following command

CL.exe /c example.cxx
link.exe /OUT:"example.dll" /DLL example.obj 

When I tried to use the library,

Square* square; square->area()

I got the error messages. What's wrong or missing?

example_unittest.obj : error LNK2001: unresolved external symbol "public: virtual double __thiscall
...
Square::area(void)" (?area@Square@@UAENXZ)

ADDED

Following wengseng's answer, I modified the header file, and for DLL C++ code, I added

#define XYZLIBRARY_EXPORT

However, I still got errors.

SOLVED

For main program that links example.dll, I didn't link example.lib.

cl /MD /EHsc gtest_main.cc example_unittest.cc /I"./include" /link /libpath:"./lib" /libpath:"." gtest_md.lib example.lib /out:gtest_md_release.exe

With the addition, everything works fine.

In DLL, i suggest to add a macro, and add XYZLIBRARY_EXPORT in pre-processor:

#if defined(XYZLIBRARY_EXPORT) // inside DLL
#   define XYZAPI   __declspec(dllexport)
#else // outside DLL
#   define XYZAPI   __declspec(dllimport)
#endif  // XYZLIBRARY_EXPORT

class XYZAPI Circle  

It will export the Circle class.

In EXE, import the Circle class, without adding pre-processor, as it will import the class by default.

You must export the Shape class to resolve "static int Shape::nshapes" error (and maybe the other errors as well).

Don't forget to link the library (example.lib) generated with the DLL

Instead of exporting a C++ class directly in a DLL, you could expose a factory function which uses the C calling convention and avoid name mangling issues.

class Shape {
  ...
};

class Circle : public Shape {
  ...
};

extern "C" Circle* newCircle();

extern "C" void deleteCircle(Circle* p);

The DLL's user can then call newCircle() to create a Circle object, do whatever it needs to do with it and then call deleteCircle() on it to get rid of it. You can't just call delete on the returned pointer because the DLL may not be linking against the same instance of the C++ runtime library as the DLL's user.

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