2013-08-18 50 views
-1

我正在为非托管C++库编写CLR包装程序。在C++/CLI代码中包含来自非托管C++代码的头文件

有两个文件我包括从非托管的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 
} 

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

如果我将包含添加到定义这些函数的非托管头文件中,我的错误将得到解决。但是,有很多功能,并且需要大量的功能。

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

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

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

编辑#2: 说我引用(body.cpp,header.h)的非托管类包含包括该定义是造成问题的功能所需的文件。但是,我的托管代码没有选择位于非托管body.cpp和header.h中的包含。

+0

所以非托管函数?我做了类似于你之前做的事情,但我不记得有这个特殊问题。为了让事情顺利进行,您更改了哪些Visual Studio项目设置? –

+0

托管代码和C++/CLI在这里没有改变任何东西。一个定义规则与只有您的本地功能的项目完全相同。 –

+0

@BenVoigt我编辑了我的问题:它是两个独立的项目,非托管类具有所有的定义和包含,但我的托管项目没有选择这些额外的非托管类。 –

回答

4

链接器错误与编译器错误是不同的一团鱼。您忘记记录您看到的确切链接程序错误,但是当您使用/ clr生效时编译代码时非常常见的问题是非C++成员函数的默认调用约定发生更改。默认值是__clrcall,这是一个为托管代码优化的约定。不带/ clr编译的函数默认为__cdecl。这改变了函数名称被破坏的方式。您在链接器错误消息中看到了这一点,表明它正在查找__clrcall函数并且找不到它。

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

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

解决方案是非常简单的:

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

谢谢

不调用其他非托管函数做工精细