我正在为我的C#项目开发一个c ++包装器。 关于如何编译最终结果,我有点困惑。所以我有这种情况:
一个项目的解决方案。该项目具有公共语言运行时支持(/ clr)。配置本机cpp文件时没有公共语言运行时支持(/ clr)和NO预编译头文件。
所以我的问题是:
原生标题:
#pragma once
#include <string>
using namespace std;
class Person
{
private:
string _name;
public:
Person(string name);
~Person();
string GetName();
};
原生cpp:
#include "stdafx.h"
#include "Person.h"
Person::Person(string name)
{
_name = name;
}
Person::~Person()
{
}
string Person::GetName()
{
return _name;
}
C ++包装器标头
#pragma once
#include <msclr\marshal_cppstd.h>
#pragma unmanaged
#include "Person.h"
using namespace System;
using namespace msclr::interop;
namespace WrapperLib{
public ref class PersonManaged
{
private:
Person *_person;
public:
PersonManaged(String ^name){
_person= new Person(marshal_as<std::string>(name));
}
~PersonManaged()
{
delete _person;
_person = 0;
}
String ^Getname(){
return gcnew String(_person->GetName().c_str());
}
};
}
编辑:
谢谢你的答案Luaan!这有帮助!我下载ILSpy并打开混合程序集。我也在那里找到了我原生的Person课程。
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[NativeCppClass, UnsafeValueType]
[StructLayout(LayoutKind.Sequential, Size = 24)]
internal struct Person
{
}
现在是什么样的?有像System an System.Runtime这样的.Net使用,但还有NativeCppClass的归属?
答案 0 :(得分:1)
您可以预编译标头 - 问题是托管预编译标头与本机预编译标头不兼容。来自MSDN:
/ clr下支持预编译头文件。但是,如果只使用/ clr编译一些CPP文件(将其余部分编译为本机),则需要进行一些更改,因为使用/ clr生成的预编译头与不使用/ clr生成的头不兼容。这种不兼容性是由于/ clr生成并需要元数据。因此,编译/ clr的模块不能使用不包含元数据的预编译头,而非/ clr模块不能使用包含元数据的预编译头文件。
article还描述了如何通过强制两个不同的预编译头文件来解决这个问题,一个是.NET,另一个是本机。但这只适用于大型项目。
至于第二个问题,这取决于。最终结果是本机DLL或混合托管/本机程序集 - 在这种情况下,我打赌后者。我只使用C ++ / CLI来生成本机类型的.NET包装器,所以我可能错了。但是很容易检查 - 只是编译,并尝试在生成的DLL上使用类似ILSpy的东西 - 如果它工作,它是一个.NET程序集,如果没有,它是一个本机DLL。
如果情况确实如此,那么是的,本机代码只是机器代码,而托管部分就像往常一样。有关详细信息,请参阅Mixed assemblies。