开发者

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, everythin开发者_如何学JAVAg 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.


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜