我之前问过这个问题。
How to pass C++ Struct To C# DLL ?
现在我正在尝试嵌套结构编码(marshal)。
我已经替换了这样的结构。
typedef struct TKeyValue
{
char Key[15];
char Value[15];
} TKeyValue;
typedef struct MyStruct
{
TKeyValue *KeyValues[1];
} TMyStruct;
typedef int (__stdcall *DoSomething)(char [],char[],TMyStruct *);
调用DLL函数
void __fastcall TForm1::btnInvokeMethodClick(TObject *Sender)
{
wchar_t buf[256];
String DLL_FILENAME = "ClassLibrary1.dll";
HINSTANCE dllHandle = NULL;
dllHandle = LoadLibrary(DLL_FILENAME.c_str());
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
OutputDebugStringW(buf);
if(dllHandle == NULL) return;
DoSomething xDoSomething = (DoSomething)GetProcAddress(dllHandle, "DoSomething");
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
OutputDebugStringW(buf);
if (xDoSomething == NULL) return;
try
{
TMyStruct aMyStruct;
char parameter1[15];
char parameter2[15];
strcpy(parameter1,"value1");
strcpy(parameter2,"value2");
int result = xDoSomething(parameter1,parameter2,&aMyStruct);
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
OutputDebugStringW(buf);
//access violation at this line
ShowMessage(aMyStruct.KeyValue[0]->Key);
}
catch(EAccessViolation &err)
{
ShowMessage(err.Message);
}
FreeLibrary(dllHandle);
C# 端
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct KeyValue
{
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public string Key;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public string Value;
}
[ComVisible(true)]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MyStruct
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public KeyValue[] KeyValues;
}
[DllExport("DoSomething", CallingConvention = CallingConvention.StdCall)]
public static int DoSomething(string tcKnVkn, string sifre, ref MyStruct myStruct)
{
try
{
MyStruct.KeyValues[0].Key = "key 1";
MyStruct.KeyValues[0].Value = "value 1";
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
}
return 2;
}
当我编译我的项目并运行时,它在访问 TKeyValue 的 Key 字段后抛出访问冲突错误 aMyStruct.KeyValue[0]->Key
我错了什么?
谢谢。
最佳答案
这里的问题是您的 Arrays
字段。 C++ 声明是:
char *Array[3]; // 3 pointers, uses up 12 bytes (32bit system)
这意味着一个包含 3 个指针的数组。稍等片刻,考虑一下它与字符串的差距——它不是包含您传递的字符的连续内存块,您传递的是一个数字。如果你想传递 3 个 C 字符串,你应该像这样声明它(不是你顺便发送的,你需要在 C# 端使用不同的属性):
char Array[15][3]; // 3 strings, uses up 45 bytes
您在这些指针中发送垃圾,当 C 代码试图取消引用它们时,它会发生访问冲突。
关于c# - 在 C++ 中使用 C# 嵌套结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32585982/