【问题标题】:Compile result for native C++ code mixed with managed code for .Net import本机 C++ 代码与 .Net 导入的托管代码混合的编译结果
【发布时间】:2015-06-25 07:09:21
【问题描述】:

我正在为我的 C# 项目开发一个 c++ 包装器。 我对最终结果的编译方式有点困惑。所以我有这种情况:

一个项目的解决方案。该项目具有公共语言运行时支持 (/clr)。本机 cpp 文件配置为没有公共语言运行时支持 (/clr) 并且没有预编译头文件。

所以我的问题是:

  1. 为什么我必须对原生 cpp 文件使用 NO 预编译头文件?
  2. 最终结果是什么,本机代码是否编译为机器码?还是因为我使用 .Net 的包装器,所以它是 JIT?

本机标头:

    #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());
    }
};
}

编辑:

感谢滦安的回答!这有帮助!我下载了 ILSpy 并打开了混合程序集。我还在那里找到了我的本地 Person 类。

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[NativeCppClass, UnsafeValueType]
[StructLayout(LayoutKind.Sequential, Size = 24)]
internal struct Person
{
}

现在它是什么样的? .Net 有 System 和 System.Runtime 之类的用法,但也有 NativeCppClass 的属性?

【问题讨论】:

  • 请留下评论以投反对票,这样下次我知道出了什么问题...

标签: c++ .net visual-studio


【解决方案1】:

您可以拥有预编译头文件 - 问题是托管的预编译头文件与本机预编译头文件不兼容。来自 MSDN:

/clr 下支持预编译的头文件。但是,如果您只使用 /clr 编译部分 CPP 文件(将其余文件编译为本地文件),则需要进行一些更改,因为使用 /clr 生成的预编译头文件与不使用 /clr 生成的头文件不兼容。这种不兼容是因为 /clr 生成并需要元数据。因此 /clr 编译的模块不能使用不包含元数据的预编译头文件,非 /clr 模块也不能使用包含元数据的预编译头文件。

article 还描述了如何通过强制使用两个不同的预编译头文件来解决这个问题,一个是 .NET,一个是原生的。不过,这只对大型项目有意义。

至于第二个问题,看情况而定。最终结果要么是原生 DLL,要么是混合的托管/原生程序集——在这种情况下,我敢打赌后者。不过,我只将 C++/CLI 用于本机类型的 .NET 包装器,所以我可能错了。不过,它很容易检查 - 只需编译,然后尝试在生成的 DLL 上使用 ILSpy 之类的东西 - 如果它有效,则它是一个 .NET 程序集,如果它不起作用,它是一个本机 DLL。

如果确实如此,那么是的,本机代码只是机器代码,而托管部分像往常一样是 IL。如需进一步参考,请参阅Mixed assemblies

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多