Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

list of structs from managed C++ to C#

First off, I would like to reference to this question: Sharing variables between C# and C++.

It seems to be what I'm looking for, but when trying to implement this, I get some errors.

First off this is my code:

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

There are quite some errors but what it comes down to are these three errors:

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

I also get a red marking under the code List data = _wrapper.getData(); when I hover my cursor over it:

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

How can I solve this?

edit:

I changed public struct MyPoint into public value struct MyPoint reducing the amount of errors from 58 to 1. the error I have now are:

Cannot implicitly convert type 'System.Collections.Generic.List<CppWrapping.MyPoint>' to 'System.Collections.Generic.List<ProjectA.MyLinker.MyPoint_t>'
like image 405
Danahi Avatar asked Mar 07 '13 14:03

Danahi


1 Answers

public struct MyPoint {}

This declares an unmanaged struct, your C# code cannot access it since it is exported as an opaque value type without any members. You must declare it as

public value struct MyPoint {}

Next thing to do is delete the MyPoint_t declaration from your C# code. Type identity includes the assembly that the type came from so MyPoint_t is not compatible with MyPoint. You can simply use the MyPoint type from the C++/CLI assembly:

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

or simply take advantage of type inference in C#:

var data = _wrapper.getData();
like image 68
Hans Passant Avatar answered Oct 20 '22 02:10

Hans Passant