我试图用C#代码调用C函数:
typedef char IPTriggerNameType[256];
typedef unsigned long COMM_HANDLE;
typedef BYTE GUID_TYPE[16];
typedef long LONGINT;
typedef struct {
GUID_TYPE Guid;
IPTriggerNameType Name;
}IPCAM_GENERIC_EVENT_ID;
typedef struct {
IPCAM_GENERIC_EVENT_ID EventId;
LONGINT RelatedTriggerId;
LONGINT ObsoleteEvent;
}IPCAM_GENERIC_EVENT_INFO;
typedef struct
{
LONGINT NumOfEvents;
IPCAM_GENERIC_EVENT_INFO *GenericEventsList;
}VID_CHANNEL_GENERIC_EVENTS_STRUCT;
int __stdcall GetGenericEvents(
/* Inputs: */
COMM_HANDLE Handle,
LONGINT MaxNumOfChannelsInTable,
LONGINT MaxNumOfEventsPerChannel,
/* Outputs: */
LONGINT *NumOfChannels,
VID_CHANNEL_GENERIC_EVENTS_STRUCT *ChannelsEventsTable);
和C#等价物如下:
[StructLayout(LayoutKind.Sequential)]
public struct IPCAM_GENERIC_EVENT_ID
{
[MarshalAs(UnmanagedType.LPArray, SizeConst = 16)]
public byte[] Guid;
[MarshalAs(UnmanagedType.LPArray, SizeConst = 256)]
public char[] Name;
};
[StructLayout(LayoutKind.Sequential)]
public struct IPCAM_GENERIC_EVENT_INFO
{
public IPCAM_GENERIC_EVENT_ID EventId;
public int RelatedTriggerId;
public int ObsoleteEvent;
}
[StructLayout(LayoutKind.Sequential)]
public struct VID_CHANNEL_GENERIC_EVENTS_STRUCT
{
public int NumOfEvents;
[MarshalAs(UnmanagedType.LPArray, SizeConst = 100)]
public IPCAM_GENERIC_EVENT_INFO[] GenericEventsList;
}
[DllImport(dllName)]
public static extern int GetGenericEvents(
/* Inputs: */
int Handle,
int MaxNumOfChannelsInTable,
int MaxNumOfEventsPerChannel,
/* Outputs: */
out int NumOfChannels,
out VID_CHANNEL_GENERIC_EVENTS_STRUCT[] ChannelsEventsTable);
int numOfChannels = 16, actualNumOfChannels = 0;
int maxNumOfEvents = 100;
VID_CHANNEL_GENERIC_EVENTS_STRUCT[] genericEventsList = new VID_CHANNEL_GENERIC_EVENTS_STRUCT[numOfChannels];
for (int i = 0; i < numOfChannels; i++)
{
genericEventsList[i].GenericEventsList = new IPCAM_GENERIC_EVENT_INFO[maxNumOfEvents];
}
GetGenericEvents(conn, numOfChannels, maxNumOfEvents, out actualNumOfChannels, out genericEventsList);
当调用C#方法时,我得到异常,导致应用程序崩溃:
托管调试助手'FatalExecutionEngineError'检测到了 'My.exe'中的问题。
其他信息:运行时遇到致命错误。该 错误的地址是0x72a6cf41,在线程0x5a98上。错误 代码是0xc0000005。此错误可能是CLR或中的错误 用户代码的不安全或不可验证部分。这个的常见来源 错误包括COM-interop或PInvoke的用户封送错误 可能会破坏堆栈。
我做错了什么?
答案 0 :(得分:-1)
字段:
VID_CHANNEL_GENERIC_EVENTS_STRUCT.GenericEventsList
是一个指针,声明为:
IPCAM_GENERIC_EVENT_INFO *GenericEventsList
但是你将它声明为一个数组,包含在结构中:
[MarshalAs(UnmanagedType.LPArray, SizeConst = 100)]
public IPCAM_GENERIC_EVENT_INFO[] GenericEventsList;
您可以尝试使用IntPtr和Marshal.AllocHGlobal。看看这个:How use pinvoke for C struct array pointer to C#