//声明
typedef int SMTK_INT;
typedef unsigned int SMTK_UINT;
typedef unsigned long SMTK_DWORD;
typedef unsigned long SMTK_HANDLE;
//结构typedef struct _tagSmtkChannel /* 通道 */
{
SMTK_INT nID; /* 通道号 */
SMTK_INT nType; /* 见(通道类型定义) */
char szName[StringLength]; /* 通道名称 */
} SmtkChannel, *PSmtkChannel;typedef struct _tagSmtkDeviceResource /* 设备资源 */
{
char szPUID[16]; /* PUID */
char szName[StringLength]; /* 设备名称 */
SMTK_INT nChannelCount; /* 通道数量 */
SmtkChannel stChannel[1]; /* 通道数组 */
} SmtkDeviceResource, *PSmtkDeviceResource;
//方法/**************** 设备配置接口 ***************/
SMTK_INT SMTK_GetDeviceResource(SMTK_HANDLE hHandle, PSmtkDeviceResource pDeviceResource, SMTK_DWORD dwBufferLength);
//调用
m_sWndPair[m_iWndPair].hSmtk 指设备信息
m_sWndPair[m_iWndPair].hSmtk = SMTK_Login(csUser, csPas, szBufIP, 3456);
BYTE Buffer[1024] = {0};
SmtkDeviceResource* pSmtkDeviceResource = (SmtkDeviceResource*)Buffer;
SMTK_INT iGet = SMTK_GetDeviceResource(m_sWndPair[m_iWndPair].hSmtk, pSmtkDeviceResource, 1024);
if(iGet != 0)
{
MessageBox("获取设备资源失败!");
return;
}下面是我的
/// <summary>
/// 设备资源
/// </summary>
public struct SmtkDeviceResource
{
///</summary>
/// char szPUID[16]; szPUID
/// </summary>
public string szPUID; ///</summary>
/// char szPUID[32]; szName 设备名称
/// </summary>
public string szName;
/// <summary>
/// 通道数量
/// </summary>
public int nChannelCount;
/// <summary>
/// 通道数组
/// </summary>
///[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public SmtkChannel[] stChannel;
} ///通道信息
public struct SmtkChannel
{
/// <summary>
/// 通道号
/// </summary>
public int nID; /// <summary>
/// 见(通道类型定义)
/// </summary>
public int nType; ///</summary>
/// char szPUID[32]; szName 通道名称
/// </summary>
public string szName;
} /// <summary>
/// 获取设备信息
/// </summary>
/// <param name="hHandle"></param>
/// <param name="pDeviceResource"></param>
/// <param name="dwBufferLength"></param>
/// <returns></returns> [DllImport("SMTK.dll")]
public static extern int SMTK_GetDeviceResource(IntPtr hHandle, IntPtr pDeviceResource, int dwBufferLength);
//调用
byte[] vBuffer = new byte[1024];
IntPtr vAddress = Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0); // 取得内存首地址 int cmd = SmartSDK.SMTK_GetDeviceResource(m_hSmtk, vAddress, vBuffer.Length); SmtkDeviceResource entries = (SmtkDeviceResource)BytesToStruct(vBuffer, typeof(SmtkDeviceResource));报 C# 尝试读取或写入受保护的内存。这通常指示其他内存已损坏
求高人指教
private static object BytesToStruct(byte[] bytes, Type strcutType)
{
int size = Marshal.SizeOf(strcutType);
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.Copy(bytes, 0, buffer, size);
return Marshal.PtrToStructure(buffer, strcutType);
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
typedef int SMTK_INT;
typedef unsigned int SMTK_UINT;
typedef unsigned long SMTK_DWORD;
typedef unsigned long SMTK_HANDLE;
//结构typedef struct _tagSmtkChannel /* 通道 */
{
SMTK_INT nID; /* 通道号 */
SMTK_INT nType; /* 见(通道类型定义) */
char szName[StringLength]; /* 通道名称 */
} SmtkChannel, *PSmtkChannel;typedef struct _tagSmtkDeviceResource /* 设备资源 */
{
char szPUID[16]; /* PUID */
char szName[StringLength]; /* 设备名称 */
SMTK_INT nChannelCount; /* 通道数量 */
SmtkChannel stChannel[1]; /* 通道数组 */
} SmtkDeviceResource, *PSmtkDeviceResource;
//方法/**************** 设备配置接口 ***************/
SMTK_INT SMTK_GetDeviceResource(SMTK_HANDLE hHandle, PSmtkDeviceResource pDeviceResource, SMTK_DWORD dwBufferLength);
//调用
m_sWndPair[m_iWndPair].hSmtk 指设备信息
m_sWndPair[m_iWndPair].hSmtk = SMTK_Login(csUser, csPas, szBufIP, 3456);
BYTE Buffer[1024] = {0};
SmtkDeviceResource* pSmtkDeviceResource = (SmtkDeviceResource*)Buffer;
SMTK_INT iGet = SMTK_GetDeviceResource(m_sWndPair[m_iWndPair].hSmtk, pSmtkDeviceResource, 1024);
if(iGet != 0)
{
MessageBox("获取设备资源失败!");
return;
}下面是我的
/// <summary>
/// 设备资源
/// </summary>
public struct SmtkDeviceResource
{
///</summary>
/// char szPUID[16]; szPUID
/// </summary>
public string szPUID; ///</summary>
/// char szPUID[32]; szName 设备名称
/// </summary>
public string szName;
/// <summary>
/// 通道数量
/// </summary>
public int nChannelCount;
/// <summary>
/// 通道数组
/// </summary>
///[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public SmtkChannel[] stChannel;
} ///通道信息
public struct SmtkChannel
{
/// <summary>
/// 通道号
/// </summary>
public int nID; /// <summary>
/// 见(通道类型定义)
/// </summary>
public int nType; ///</summary>
/// char szPUID[32]; szName 通道名称
/// </summary>
public string szName;
} /// <summary>
/// 获取设备信息
/// </summary>
/// <param name="hHandle"></param>
/// <param name="pDeviceResource"></param>
/// <param name="dwBufferLength"></param>
/// <returns></returns> [DllImport("SMTK.dll")]
public static extern int SMTK_GetDeviceResource(IntPtr hHandle, IntPtr pDeviceResource, int dwBufferLength);
//调用
byte[] vBuffer = new byte[1024];
IntPtr vAddress = Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0); // 取得内存首地址 int cmd = SmartSDK.SMTK_GetDeviceResource(m_hSmtk, vAddress, vBuffer.Length); SmtkDeviceResource entries = (SmtkDeviceResource)BytesToStruct(vBuffer, typeof(SmtkDeviceResource));报 C# 尝试读取或写入受保护的内存。这通常指示其他内存已损坏
求高人指教
private static object BytesToStruct(byte[] bytes, Type strcutType)
{
int size = Marshal.SizeOf(strcutType);
IntPtr buffer = Marshal.AllocHGlobal(size);
try
{
Marshal.Copy(bytes, 0, buffer, size);
return Marshal.PtrToStructure(buffer, strcutType);
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
然后通过引用可以实现调用
这样改代码其不痛苦
public struct SmtkDeviceResource
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string szPUID; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szName; public uint nChannelCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public SmtkChannel[] stChannel;
} ///通道信息
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SmtkChannel
{
public uint nID; public uint nType; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szName;
}
[DllImport("SMTK.dll")]
public static extern int SMTK_GetDeviceResource(uint hHandle, ref SmtkDeviceResource pDeviceResource, uint dwBufferLength);
有个疑问:
typedef struct _tagSmtkDeviceResource /* 设备资源 */
{
char szPUID[16]; /* PUID */
char szName[StringLength]; /* 设备名称 */
SMTK_INT nChannelCount; /* 通道数量 */
SmtkChannel stChannel[1]; /* 通道数组 */
} SmtkDeviceResource, *PSmtkDeviceResource;既然结构体里有指示通道数量 的成员,后面定义一个SmtkChannel stChannel[1]; /* 通道数组 */
这是一种很奇怪的做法,直接定义指针更合理些。