编译与.Net导入的托管代码混合的本机C ++代码的结果

时间:2015-06-25 07:09:22

标签: c++ .net visual-studio

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

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

所以我的问题是:

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

        #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的归属?

1 个答案:

答案 0 :(得分:1)

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

  

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

article还描述了如何通过强制两个不同的预编译头文件来解决这个问题,一个是.NET,另一个是本机。但这只适用于大型项目。

至于第二个问题,这取决于。最终结果是本机DLL或混合托管/本机程序集 - 在这种情况下,我打赌后者。我只使用C ++ / CLI来生成本机类型的.NET包装器,所以我可能错了。但是很容易检查 - 只是编译,并尝试在生成的DLL上使用类似ILSpy的东西 - 如果它工作,它是一个.NET程序集,如果没有,它是一个本机DLL。

如果情况确实如此,那么是的,本机代码只是机器代码,而托管部分就像往常一样。有关详细信息,请参阅Mixed assemblies