Передача массива 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;
}
Большое спасибо!