从托管C ++到C#的结构列表

时间:2013-03-07 14:40:48

标签: c# list managed-c++

首先,我想提一下这个问题:Sharing variables between C# and C++

这似乎是我正在寻找的,但在尝试实现这一点时,我遇到了一些错误。

首先,这是我的代码:

C ++ MyCppWrapper.h

namespace CppWrapping
{
    #pragma pack(1)
    public struct MyPoint
    {
    public: 
        float X;
        float Y;
        float Z;
        unsigned char R;
        unsigned char G;
        unsigned char B;
        unsigned char A;

    }MyPoint_t;
    #pragma pack()

    public ref class MyCppWrapper
    {
    public:
        MyCpplWrapper(void);
        List<MyPoint>^ getData();
    };
};

C ++ MyCppWrapper.cpp

List<MyPoint>^ MyCppWrapper::getData()
{
    List<MyPoint>^ temp = gcnew List<MyPoint>();
    for (int i = 0; i < Data.Length; i++)
    {
        PointT& pt = Data.points[i];
        MyPoint holder = MyPoint();
        holder.X = pt.x;
        holder.Y = pt.y;
        holder.Z = pt.z;
        holder.R = pt.r;
        holder.G = pt.g;
        holder.B = pt.b;
        holder.A = pt.a;
        temp[i] = holder;
    }
    return temp;
}

C#MyLinker.cs

[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct MyPoint_t
{
    public float X;
    public float Y;
    public float Z;
    public byte R;
    public byte G;
    public byte B;
    public byte A;
};

public void getData()
{
    _wrapper = new MyCppWrapper();
    List<MyPoint_t> data = _wrapper.getData();
}

有一些错误,但归结为这三个错误:

error C3225: generic type argument for 'T' cannot be 'CppWrapping::MyPoint', it must be a value type or a handle to a reference type

'CppWrapping.MyPoint' is inaccessible due to its protection level

'CppWrapping.MyCppWrapper.getData()' is inaccessible due to its protection level

当我将光标悬停在代码List data = _wrapper.getData();上时,我也会得到一个红色标记:

Cannot convert source type 'System.Collections.Generic.List<CppWrapping.MyPoint>' to target type 'System.Collections.Generic.List<ProjectA.MyLinker.MyPoint_t>'

我该如何解决这个问题?

编辑:

我将public struct MyPoint更改为public value struct MyPoint 将错误数量从58减少到1。 我现在的错误是:

Cannot implicitly convert type 'System.Collections.Generic.List<CppWrapping.MyPoint>' to 'System.Collections.Generic.List<ProjectA.MyLinker.MyPoint_t>'

1 个答案:

答案 0 :(得分:4)

public struct MyPoint {}

这声明了一个非托管结构,您的C#代码无法访问它,因为它被导出为不带任何成员的不透明值类型。您必须将其声明为

public value struct MyPoint {}

接下来要做的是从C#代码中删除MyPoint_t声明。类型标识包括类型来自的程序集,因此MyPoint_t与MyPoint不兼容。您只需使用C ++ / CLI程序集中的MyPoint类型:

_wrapper = new MyCppWrapper();
List<MyPoint> data = _wrapper.getData();

或简单地利用C#中的类型推断:

var data = _wrapper.getData();