0

I'm writing a CLR wrapper for an unmanaged C++ library.

There are two files I'm including from the unmanaged lib:

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

Then I'm writing CLI implementations for the unmanaged library functions:

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

However, if my Unmanaged function contains calls to other functions that are defined in other unmanaged header files. This causes a compiler linkage error.

If I add includes to the unmanaged headers that define these functions, my errors get resolved. However, there is a lot of functions, and a lot of includes required.

Is there a different way to approach this?

EDIT: P.S. My managed code is in a separate Visual Studio project (output - DLL), and the compile settings are set to /CLR. Unmanaged code is in a separate Win32 project (output - DLL).

Also, after more research I concluded that theoretically I could set my Win32 unmanaged project to CLR and just add my managed classes and headers in there as an entry point, and then it would all compile into a single DLL file. That would probably solve (?) the linkage errors. However, I would prefer to preserve the loose coupling as well as the additional series of problems that can raise from setting my unmanaged project to CLR.

EDIT #2: The unmanaged class that I'm referencing (body.cpp, header.h) contains includes to the required files that define the functions that are causing the problems. However, my managed code doesn't pick up on the includes that are in the unmanaged body.cpp and header.h.

4

2 回答 2

6

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

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

#pragma managed(push, off)
#include "unmanagedHeader.h"
#pragma managed(pop)
于 2013-08-18T20:20:49.187 回答
1

解决方案相当简单:

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

谢谢

于 2013-08-18T20:33:40.187 回答