从C ++类制作Visual C ++ DLL

我有以下C ++代码来制作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); }; 

我有__declspec,

 class __declspec(dllexport) Circle 

我可以用下面的命令build立一个dll

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

当我试图使用图书馆,

 Square* square; square->area() 

我收到了错误消息。 有什么问题或缺失?

 example_unittest.obj:错误LNK2001:无法parsing的外部符号“public:virtual double __thiscall
 ...
 Square :: area(void)“(?area @ Square @@ UAENXZ)

添加

在wengseng的回答之后,我修改了头文件,并添加了DLL C ++代码

 #define XYZLIBRARY_EXPORT 

不过,我仍然有错误。

解决了

对于链接example.dll的主程序,我没有链接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 

除此之外,一切工作正常。

在DLL中,我建议添加一个宏,并在预处理器中添加XYZLIBRARY_EXPORT:

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

它将导出Circle类。

在EXE中,导入Circle类,而不添加预处理器,因为它将默认导入类。

而不是直接在一个DLL中导出一个C ++类,你可以公开一个使用C调用约定的工厂函数,并避免名称修改问题。

 class Shape { ... }; class Circle : public Shape { ... }; extern "C" Circle* newCircle(); extern "C" void deleteCircle(Circle* p); 

然后DLL的用户可以调用newCircle()来创建一个Circle对象,做它需要做的事情,然后调用deleteCircle()来摆脱它。 你不能仅仅在返回的指针上调用delete,因为这个DLL可能不会和DLL的用户链接到C ++运行时库的同一个实例上。

您必须导出Shape类来解析“static int Shape :: nshapes”错误(也可能是其他错误)。

不要忘记链接使用DLL生成的库(example.lib)