制作 Visual C++来自 C++ 的 DLL班级

发布于 2024-10-11 17:43:43 字数 1536 浏览 5 评论 0原文

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

添加后,一切正常。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

漫漫岁月 2024-10-18 17:43:43

在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 类,无需添加预处理器,因为它会默认导入该类。

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.

美男兮 2024-10-18 17:43:43

您可以公开使用 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++ 运行时库的同一实例。

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.

薄情伤 2024-10-18 17:43:43

您必须导出 Shape 类才能解决“static int Shape::nshapes”错误(也可能还有其他错误)。

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文