C# 中的 Marshall C++ 结构
Posted
技术标签:
【中文标题】C# 中的 Marshall C++ 结构【英文标题】:Marshall C++ structure in C# 【发布时间】:2014-09-21 15:26:43 【问题描述】:我在这里提到了类似的问题,但没有得到我的问题的解决方案。
编组问题。我尝试将 C++ 结构转换为 C#,但做不到。我在 pinvoke.net 中搜索了任何解决方案的提示,但找不到任何东西。请帮帮我!
错误消息
An unhandled exception of type 'System.AccessViolationException' occurred in Unknown Module.
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
C++ 结构
typedef struct SDK_ALARM_INFO
int nChannel;
int iEvent;
int iStatus;
SDK_SYSTEM_TIME SysTime;
SDK_AlarmInfo;
typedef struct SDK_SYSTEM_TIME
int year;
int month;
int day;
int wday;
int hour;
int minute;
int second;
int isdst;
SDK_SYSTEM_TIME;
转换后的结构 C#:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SDK_ALARM_INFO
public int nChannel;
public int iEvent;
public int iStatus;
[MarshalAs(UnmanagedType.Struct)]
public SDK_SYSTEM_TIME SysTime;
;
public struct SDK_SYSTEM_TIME
public int year;
public int month;
public int day;
public int wday;
public int hour;
public int minute;
public int second;
public int isdst;
编组指向结构的指针时出错。
C# 代码
private XMSDK.fMessCallBack msgcallback;
bool MessCallBack(int lLoginID, string pBuf,uint dwBufLen, IntPtr dwUser)
SDK_ALARM_INFO ai = new SDK_ALARM_INFO();
//getting error bottom line
ai = (SDK_ALARM_INFO) Marshal.PtrToStructure(dwUser, typeof(SDK_ALARM_INFO)); // getting error this line
MessageBox.Show("Event: " + ai.iEvent.ToString() + " - Channel: " + ai.nChannel + " - GTime : " + ai.SysTime);
return form.DealwithAlarm(lLoginID,pBuf,dwBufLen);
public int InitSDK()
//...
msgcallback = new XMSDK.fMessCallBack(MessCallBack);
XMSDK.H264_DVR_SetDVRMessCallBack(msgcallback, this.Handle);
//...
MessCallBack 函数 C#
class XMSDK
// ...
public delegate bool fMessCallBack(int lLoginID, string pBuf, uint dwBufLen, IntPtr dwUser);
[DllImport("NetSdk.dll")]
public static extern void H264_DVR_SetDVRMessCallBack(fMessCallBack cbAlarmcallback, IntPtr lUser);
//...
我认为,结构转换错误和可能导致的错误。等待帮助。谢谢!
【问题讨论】:
Please add the exact error messages to you question. 对不起,我更新了帖子。 【参考方案1】:结构声明看起来不错,但请确保您正确理解该 SDK。 SDK_ALARM_INFO
很有可能在 pBuf
参数中返回,而不是在 dwUser
中。通常当某些SDK允许您使用用户定义的指针注册回调时,该指针被传递给回调方法(在这种情况下为dwUser
),所以我认为在你的情况下dwUser
实际上等于this.Handle
。
尝试将回调和方法声明更改为
delegate bool fMessCallBack(int lLoginID, IntPtr pBuf, uint dwBufLen, IntPtr dwUser);
bool MessCallBack(int lLoginID, IntPtr pBuf, uint dwBufLen, IntPtr dwUser);
然后打电话
ai = (SDK_ALARM_INFO) Marshal.PtrToStructure(pBuf, typeof(SDK_ALARM_INFO));
这可能会有所帮助。
【讨论】:
以上是关于C# 中的 Marshall C++ 结构的主要内容,如果未能解决你的问题,请参考以下文章
在 c# 中使用 ifdef 和联合的 Marshall 结构