在C ++ / CLI代码中包含来自非托管C ++代码的头文件

时间:2013-08-18 19:16:44

标签: c++-cli unmanaged

我正在为一个非托管C ++库编写一个CLR包装器。

我从非托管lib中包含两个文件:

//MyCLIWrapper.h
#include "C:\PATH\TO\UNMANAGED\Header.h"
#include "C:\PATH\TO\UNMANAGED\Body.cpp"

然后我正在为非托管库函数编写CLI实现:

//MyCLIWrapper.h
// includes ...
void MyCLIWrapper::ManagedFunction()
{
  UnmanagedFunction(); // this function is called successfuly
}

但是,如果我的Unmanaged函数包含对其他非托管头文件中定义的其他函数的调用。这会导致编译器链接错误。

如果我将include添加到定义这些函数的非托管标头,我的错误就会得到解决。但是,有很多功能,需要很多包括。

有没有不同的方法来解决这个问题?

修改 附: 我的托管代码位于单独的Visual Studio项目(输出 - DLL)中,编译设置设置为/ CLR。非托管代码位于单独的Win32项目(输出 - DLL)中。

此外,经过更多的研究,我得出结论,理论上我可以将我的Win32非托管项目设置为CLR,只需将我的托管类和标头添加到其中作为入口点,然后它将全部编译成单个DLL文件。这可能会解决(?)链接错误。但是,我更愿意保留松散耦合以及从将非托管项目设置为CLR可能引发的其他一系列问题。

编辑#2: 我正在引用的非托管类(body.cpp,header.h)包含必需的文件,这些文件定义了导致问题的函数。但是,我的托管代码没有获取非托管body.cpp和header.h中的包含。

2 个答案:

答案 0 :(得分:4)

链接器错误与编译器错误不同。您忘记记录您看到的确切链接器错误,但是当您使用/ clr编译代码时,一个非常常见的错误是非C ++成员函数的默认调用约定发生了变化。默认值为__clrcall,这是一种针对托管代码进行了优化的约定。虽然没有/ clr编译的函数默认为__cdecl。这改变了函数名称被破坏的方式。您在链接器错误消息中看到这一点,显示它正在查找__clrcall函数但找不到它。

您需要使用__cdecl在.h文件中显式声明您的函数。或者告诉编译器这些函数不是托管代码。哪种解决方法最好:

#pragma managed(push, off)
#include "unmanagedHeader.h"
#pragma managed(pop)

答案 1 :(得分:1)

解决方案非常简单:

  1. 我将非托管和托管项目添加到Visual Studio中的单个解决方案中。
  2. 将非托管项目的“配置类型”设置为“静态库”(.lib)。
  3. 右键单击托管项目 - >参考文献 - >添加参考 - >项目 - > - >添加参考。
  4. 然后在我的托管类中,我包含了header.h(仅),就像我在我的问题中一样。
  5. 编译成功!
  6. 谢谢