首页 文章

从C类制作Visual C DLL

提问于
浏览
1

我有以下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

我可以使用以下命令构建一个dll

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

当我试图使用该库时,

Square* square; square->area()

我收到了错误消息 . 有什么不对或缺失?

example_unittest.obj : error LNK2001: unresolved external symbol "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

除此之外,一切正常 .

3 回答

  • 6

    在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类,而不添加预处理器,因为它将默认导入该类 .

  • 2

    您可以公开一个使用C调用约定的工厂函数,而不是直接在DLL中导出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运行时库的同一实例 .

  • 2

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

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

相关问题