C декларация:
struct t_name
{
char first_name[128];
char nickname[128];
int32_t words[7];
uint16_t parts_of_speech[7];
uint32_t language;
bool has_name;
};
char* Translation_TranslateNameEnglish(DFHackObject* trans, const t_name* name);
Как я это делаю в C #:
[StructLayout(LayoutKind.Sequential), Serializable]
public struct DFName
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string FirstName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string NickName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public int[] Words;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public ushort[] PartsOfSpeech;
public uint Language;
public bool HasName;
}
[DllImport(DllName)]
public static extern string Translation_TranslateNameEnglish(IntPtr ptr, ref DFName name);
Звонок:
DFHack.Translation_TranslateNameEnglish(translation, ref name)
Работа с IntPtr в качестве первого параметра не проблема, у меня есть такая же работа в аналогичных вызовах. Структура DFName заполняется в другом вызове и содержит действительные данные.
Однако, что не работает, так это вызов TranslateNameEnglish. Когда эта строка выполняется, я получаю сообщение об ошибке «Попытка чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена».
Что я делаю не так?
То, что я забыл упомянуть, что может быть важным: структура DFName извлекается как часть другой структуры.
[StructLayout(LayoutKind.Sequential), Serializable]
public struct DFCreature
{
// Snip
public DFName Name;
// Snip
}
который извлекается методом
public static extern int Creatures_ReadCreature(IntPtr ptr, uint index, out DFCreature creature);