Я изучаю Rust, когда пытаюсь найти альтернативу interop C# с C/C++.Как вернуть массив структур от Rust до C#
Как можно писать код Rust как код C ниже? Это мой Rust код до сих пор, без опции Маршалла документа:
pub struct PackChar { id: u32, val_str: String, }
#[no_mangle]
pub extern fn get_packs_char(size: u32) -> Vec<PackChar> {
let mut out_vec = Vec::new();
for i in 0 .. size {
let int_0 = '0' as u32;
let last_char_val = int_0 + i % (126 - int_0);
let last_char = char::from_u32(last_char_val).unwrap();
let buffer = format!("abcdefgHi{}", last_char);
let pack_char = PackChar {
id: i,
val_str: buffer,
};
out_vec.push(pack_char);
}
out_vec
}
Код выше пытается воспроизвести следующий C код, который я нахожусь в состоянии взаимодействовать с как есть.
void GetPacksChar(int size, PackChar** DpArrPnt)
{
int TmpStrSize = 10;
*DpArrPnt = (PackChar*)CoTaskMemAlloc(size * sizeof(PackChar));
PackChar* CurPackPnt = *DpArrPnt;
char dummyString[]= "abcdefgHij";
for (int i = 0; i < size; i++,CurPackPnt++)
{
dummyString[TmpStrSize-1] = '0' + i % (126 - '0');
CurPackPnt->IntVal = i;
CurPackPnt->buffer = strdup(dummyString);
}
}
Этот C код может быть доступен через импорт DLL в C# как это:
[Dllimport("DllPath", CallingConvention = CallingConvention.Cdecl)]
public static extern void GetPacksChar(uint length, PackChar** ArrayStructs)
PackChar* MyPacksChar;
GetPacksChar(10, &MyPacksChar);
PackChar* CurrentPack = MyPacksChar;
var contLst = new List<PackChar>();
for (uint i = 0; i < ArrL; i++, CurrentPack++)
contlist.Add(new PackChar() {
IntVal = CurrentPack->IntVal, buffer = contLst->buffer
});
Я не знаю много о C# interop, но одно всегда верно для использования FFI с любым внешним языком: вы не должны использовать Rust-специфичные типы, такие как 'Vec' в 'extern'. Единственными видами типов, которые могут использоваться в таких функциях, являются примитивные типы, такие как целые числа, поплавки и указатели, и структуры '# [repr (C)]', которые состоят из этих типов. –