【问题标题】:Create DLL from unmanaged C++从非托管 C++ 创建 DLL
【发布时间】:2013-01-05 21:20:58
【问题描述】:

我目前有一个用非托管 C++ 编写的控制台应用程序,源代码由入口点 main 和一些其他函数组成。我需要从此代码创建一个 DLL,以便我可以在其他项目中使用它,特别是在托管 C++ 中。 (另一个问题:我是否必须为此编写一个包装类?)

由于我对托管/非托管 C++ 和创建 DLL 几乎一无所知,因此我遵循 this tutorial 并设法通过仅使用 VS2010(无 CMake)启动并运行了一个简单的 Hello World DLL。

但是,我的这个项目有很多依赖项(例如Point Cloud Library),因此我通常使用 CMake 生成 Visual Studio 2010 解决方案,然后构建为可执行文件,如PCL Tutorial 中所述。如何使用 CMake 构建将构建到 DLL 中的 VS2010 项目?

总结一下我的问题:

  1. 我有一个需要大量依赖项的非托管 C++ 代码项目。
  2. 我想用这段代码创建一个 DLL,它可以从托管 C++ 中调用。

额外信息: Windows 7、Visual Studio 2010 Ultimate、CMake 2.8.10.2

编辑: 我使用 CMake 更改了您的线路,它按预期工作。这是我添加到头文件后的内容,我在正确的轨道上吗?

MyCode.h

#ifdef MyLib_EXPORTS
#define API_DECL __declspec( dllexport )
#else 
#define API_DECL __declspec( dllimport )

#include <iostream>
#include <pcl/...>
etc...

API_DECL void myFirstFunction();
API_DECL void mySecondFunction();
#endif

MyCode.cpp:我没有对源文件进行任何更改,我应该做任何更改吗?

【问题讨论】:

  • 您的#endif 应该在包含iostream 之前关闭。
  • 我认为我的 DLL 可以正常工作了。现在来处理非托管/托管的情况。谢谢!

标签: c++ visual-studio-2010 dll cmake unmanaged


【解决方案1】:

很遗憾,我无法在托管代码部分为您提供帮助,但这就是您在 CMake 中创建 DLL 的方式:

首先,不要使用

`ADD_EXECUTABLE( YourLib SHARED yourclass.cpp yourclass.h )` 

在您的CMakeLists.txt 中,使用

`ADD_LIBRARY( YourLib SHARED yourclass.cpp yourclass.h )`

这会将解决方案配置为创建 DLL 而不是可执行文件。

但是,为了能够将此 DLL 用于您的项目,您需要导出要使用的符号。为此,您需要将__declspec( dllexport ) 添加到您的类和/或函数声明中。然后构建库将产生两个文件,一个.dll 和一个.lib。后一个是你在其他项目中使用这个库时需要的所谓的导入库。运行时需要.dll。

然而:当你想使用你的库时,你需要使用__declspec( dllimport)(而不是dllexport)。为了避免使用两个头文件,通常的方法是使用预处理器。 CMake 实际上通过在您的库项目中提供 YourLibrary_EXPORTS define 来帮助您。

总结一下:

#ifndef YOUR_CLASS_H
#define YOUR_CLASS_H

#ifdef YourLib_EXPORTS
#define API_DECL __declspec( dllexport )
#else 
#define API_DECL __declspec( dllimport )
#endif

class APIDECL YourClass  {
   void foo();
   void bar();
};

#endif // YOUR_CLASS_H

编辑: 如果您希望能够使用 C 中的这些函数(以及能够使用 C 函数的语言),您应该使用 extern "C" { 包装您的声明

extern "C" {
    API_DECL void myFirstFunction();
    API_DECL void mySecondFunction();
}

【讨论】:

  • 谢谢!我只是想检查一些事情。这是否意味着我的函数声明,例如mainFunc(int a) 应该改为__declspec( dllexport ) mainFunc(int a)?
  • 不,你不会导出你的main 函数(至少不是main 或WinMain)。这将与链接到该库的可执行文件中的主函数发生冲突。但是,如果您需要在加载 dll 时调用特定代码,请查看 [msdn.microsoft.com/en-us/library/windows/desktop/….
  • 抱歉弄乱了上一条评论中的链接:这是正确的DllMain
  • 好的,我想我明白了。所以这意味着我只需要重新声明我希望从外部访问的那些功能?在我的情况下,只有 main 函数可以访问就足够了,所以我应该选择只使用 DllMain 吗?
  • 如果它是您想在外部使用的函数(它是一个库),我会明确建议以不同的方式调用您的函数。然后就用那个名字来称呼它。
猜你喜欢
  • 2011-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 2010-10-14
  • 2020-05-03
相关资源
最近更新 更多