Передача массива struct из C# удалось C++ неуправляемым и получить изменения

Не удалось найти решение для простой задачи, пожалуйста, помогите мне найти его. По сути, я хочу передать массив struct и вернуть изменение значений структуры из неуправляемого кода. Вот мой код:

C++:

struct CPT {
    const char* Value1;
    const char* Value2;
};

extern "C" __declspec(dllexport) int ToError(CPT* cpts, const int length) {
for (size_t i = 0; i < length; i++)
{
    cpts[i].Value1 = "a";
    cpts[i].Value2 = "b";
}
return length;

}

C#:

[StructLayout(LayoutKind.Sequential)]
public struct CPT
{
    [MarshalAs(UnmanagedType.LPStr)]
    public string Value1;
    [MarshalAs(UnmanagedType.LPStr)]
    public string Value2;
}

public class Program
{        
    [DllImport("CUDALib.dll")]
    unsafe public static extern int ToError([MarshalAs(UnmanagedType.LPArray), Out] CPT[] cpts, int length);

    unsafe static void Main(string[] args)
    {
        var cptList = new List<CPT>();
        for (int i = 0; i < 5; i++)
        {
            CPT c;
            c.Value1 = $"1000{i}";
            c.Value2 = $"2000{i}";
            cptList.Add(c);
        }
        var errors = new Error[cptList.Count];
        var cpts = cptList.ToArray();
        var result = ToError(cpts, cptList.Count);
    }
}

РЕДАКТИРОВАНИЕ: Теперь все работает, я изменил структуру C++ на массив символов, затем вместо изменения свойства элементов массива я сам назначил элементы массива. C#:

[StructLayout(LayoutKind.Sequential)]
public struct ByValTStrTest
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
    public string Value;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
    public string Value2;
}
[DllImport("CUDALib.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int CallByValTStr([MarshalAs(UnmanagedType.Struct)] ref ByValTStrTest model);

    [DllImport("CUDALib.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int CallByValTStrArray([MarshalAs(UnmanagedType.LPArray, SizeConst = 2), Out] ByValTStrTest[] model, int length);

var m1 = new LPSTRTest { Value = "00000" };
        var m2 = new ByValTStrTest { Value = "0000", Value2 = "2222" };
        var m3 = new ByValTStrTest[] {
            new ByValTStrTest{ Value = "0000", Value2="2222" },
            new ByValTStrTest{ Value = "1111", Value2="3333" }
        };

        var result = CallLPSTR(ref m1);
        result = CallByValTStr(ref m2);
        result = CallByValTStrArray(m3, m3.Length);

C++:

struct ByValTStrTest {
    char Value[5];
    char Value2[5];
};

extern "C" __declspec(dllexport) int CallByValTStr(ByValTStrTest model) {
    if (strcmp(model.Value, "0000") == 0) {
        model = { "1111", "3333" };
        return 1;
    }
    return 0;
}

extern "C" __declspec(dllexport) int CallByValTStrArray(ByValTStrTest* model, int length) {
    for (size_t i = 0; i < length; i++)
    {
        model[i] = { "4444", "4444" };
    }   
    return 1;
 }

Большое спасибо!

0 ответов

Другие вопросы по тегам