C# C结构,并在C中使用C dll#
各位,我是C#的新手,在C#中使用“C”dll有问题,下面是C端代码,工作正常C# C结构,并在C中使用C dll#,c#,c,C#,C,各位,我是C#的新手,在C#中使用“C”dll有问题,下面是C端代码,工作正常 // myCode.h typedef struct _SubABC { unsigned short WordCount; unsigned char *WordData; unsigned char SpeedUp; } SubABC; typedef struct _ABC { unsigned
// myCode.h
typedef struct _SubABC
{
unsigned short WordCount;
unsigned char *WordData;
unsigned char SpeedUp;
} SubABC;
typedef struct _ABC
{
unsigned char SubFontNum;
SubABC subABC[5];
} ABC
extern __declspec(dllimport) int __stdcall MY_SetSth(unsigned char SerialNum, ABC *pABC);
//myCode.c
ABC myFun = { '\0' };
unsigned char text_c[] =
{
0x00,0x27,0xff,0xA5,0xC3, 0x00,0x27,0xff,0xA6,0x26, 0x00,0x23,0xff,0xA7,0xAE, 0x00,0x27,0xff,0xBA,0x7E,
0x00,0x27,0xff,0xC1,0x52, 0x00,0x27,0xff,0xAC,0xF9, 0x00,0x27,0xff,0x20,0x00,0x27,0xff,0x31, 0x00,0x27,0xff,0x20, 0x00,0x27,0xff,0xA4,0xC0, 0x00,0x27,0xff,0xC4,0xC1,
};
myFun.SubFontNum = 1;
myFun.subMABC[0].WordCount = sizeof(text_c);
myFun.subMABC[0].WordData = text_c;
myFun.subMABC[0].SpeedUp = 0;
int retvalue = MY_SetSth(1, &myFun);
下面是我的C代码
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SubABC
{
public ushort WordCount;
[MarshalAs(UnmanagedType.LPArray)]
public byte[] WordData;
public byte SpeedUp;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct ABC
{
public byte SubFontNum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public SubABC[] subABC;
}
[DllImport("myDLL.dll", CharSet = CharSet.Ansi)]
public extern static int MY_SetSth(byte SerialNum, ref ABC pABC);
ABC myFun = new ABC();
ABC.subABC = new SubABC[5];
unsigned char text_c[] =
{
0x00,0x27,0xff,0xA5,0xC3, 0x00,0x27,0xff,0xA6,0x26, 0x00,0x23,0xff,0xA7,0xAE, 0x00,0x27,0xff,0xBA,0x7E,
0x00,0x27,0xff,0xC1,0x52, 0x00,0x27,0xff,0xAC,0xF9, 0x00,0x27,0xff,0x20,0x00,0x27,0xff,0x31, 0x00,0x27,0xff,0x20, 0x00,0x27,0xff,0xA4,0xC0, 0x00,0x27,0xff,0xC4,0xC1,
};
myFun.SubFontNum = 1;
myFun.subMABC[0].WordCount = (ushort)text_c.Length;
myFun.subMABC[0].WordData = text_c;
myFun.subMABC[0].SpeedUp = 0;
int retvalue = MY_SetSth(1, ref myFun);
我始终获得TypeLoadException:无法封送类型为“subABC”的字段“WordData”:无效的托管/非托管类型组合(数组字段必须与ByValArray或SafeArray配对)
,因为WordData的大小未知,我无法使用ByValArray,和SafeArray getAccessViolationException:尝试读取或写入受保护内存
我试着像下面这样使用IntPtr
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SubABC
{
public ushort WordCount;
public IntPtr WordData;
public byte SpeedUp;
}
ABC.subABC[0].WordData = Marshal.AllocHGlobal(text_c.Length); ;
Marshal.Copy(text_c, 0, ABC.subABC[0].WordData, text_c.Length);
int retvalue = MY_SetSth(1, ref myFun);
我收到错误消息AccessViolationException:试图读取或写入受保护内存
有人能帮我吗?非常感谢。您能分享错误详细信息吗?您可以将WordData
定义为IntPtr
,然后将其封送至所需类型请查看此MSDN我想,您应该使用marshal.allocTaskMem
方法,而不是marshal.AllocHGlobal
看起来没问题。很难猜测“我的设置”是如何变成“我的设置”的。您必须在C端对此进行调试。嗨,Pavel,我尝试使用Marshal.allocTaskMem
,但仍然得到AccessViolationException:尝试读取或写入受保护的内存
。嗨,汉斯,对不起,这是一个打字错误,应该是我的设置。你能分享错误的详细信息吗?您可以将WordData
定义为IntPtr
,然后将其封送至所需类型请查看此MSDN我想,您应该使用marshal.allocTaskMem
方法,而不是marshal.AllocHGlobal
看起来没问题。很难猜测“我的设置”是如何变成“我的设置”的。您必须在C端对此进行调试。嗨,Pavel,我尝试使用Marshal.allocTaskMem
,但仍然得到AccessViolationException:尝试读取或写入受保护的内存
。嗨,汉斯,对不起,是打字错误,应该是我的错。