C# 调用C++dll的参数为数据结构指针的指针

EasonLouis 2016-12-05 02:43:16
C++的dll
HRESULT extern WINAPI WFSGetInfo ( HSERVICE hService, DWORD dwCategory, LPVOID lpQueryDetails, DWORD dwTimeOut, LPWFSRESULT * lppResult);

结构体
typedef struct _wfs_result
{
REQUESTID RequestID;
HSERVICE hService;
SYSTEMTIME tsTimestamp;
HRESULT hResult;
union {
DWORD dwCommandCode;
DWORD dwEventID;
} u;
LPVOID lpBuffer;
} WFSRESULT, * LPWFSRESULT;
typedef struct _wfs_idc_status
{
WORD fwDevice;
WORD fwMedia;
WORD fwRetainBin;
WORD fwSecurity;
USHORT usCards;
WORD fwChipPower;
LPSTR lpszExtra;
} WFSIDCSTATUS, *LPWFSIDCSTATUS;


c#的定义
      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct WFSRESULT1
{
public UInt32 RequestID;
public ushort hService;
public _SYSTEMTIME tsTimestamp;//对应下面的 _SYSTEMTIME
public int hResult;
public AnonymousStruct U;//对应下面的 AnonymousStruct 结构
public IntPtr lpBuffer;//返回的指针,指向_wfs_idc_status 这个结构
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct LPStruct
{
public IntPtr ptrWFSRESULT;//返回的指针,指向WFSRESULT1 这个结构
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct _wfs_idc_status
{
public UInt16 fwDevice;
public UInt16 fwMedia;
public UInt16 fwRetainBin;
public UInt16 fwSecurity;
public ushort usCards;
public UInt16 fwChipPower;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 999)]
public string lpszExtra;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct _SYSTEMTIME
{
public UInt16 wYear;
public UInt16 wMonth;
public UInt16 wDayOfWeek;
public UInt16 wDay;
public UInt16 wHour;
public UInt16 wMinute;
public UInt16 wSecond;
public UInt16 wMilliseconds;
}
[DllImport("msxfs.dll", CharSet = CharSet.Ansi)]
public static extern int WFSGetInfo(int iService, int iCategory, string sQueryDetail, int iTimeOut, ref IntPtr ptr);


C#执行
            LPStruct lpStruct = new LPStruct();
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(lpStruct));
Marshal.StructureToPtr(lpStruct, ptr, false);
int iRet = WFSGetInfo(m_service, WFS_INF_IDC_STATUS, null, 2000, ref ptr);
lpStruct = (LPStruct)Marshal.PtrToStructure(ptr, typeof(LPStruct));
WFSRESULT1 wfsR1;
wfsR1 = (WFSRESULT1)Marshal.PtrToStructure(lpStruct.ptrWFSRESULT, typeof(WFSRESULT1));//运行会在Application.Run()里面报错"未处理AccessViolationException。尝试读取或写入受保护的内存。这通常指示其他内存已损坏。"
_wfs_idc_status stat1 = (_wfs_idc_status)Marshal.PtrToStructure(wfsR1.lpBuffer, typeof(_wfs_idc_status));


请求各位高手指教,是我定义和操作结构体错误导致的吗?
...全文
209 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
EasonLouis 2016-12-05
  • 打赏
  • 举报
回复
弄好了一半,我上面用LPSTRUCT结构体里的IntPtr ptrWFSRESULT返回的指针,指向WFSRESULT1 这个结构是错的,直接使用WFSRESULT1 结构体就行。修改如下
            WFSRESULT1 wfsR1 = new WFSRESULT1();
            IntPtr ptr = IntPtr.Zero;
            int iRet = WFSGetInfo(m_service, WFS_INF_IDC_STATUS, null, 2000, ref ptr);
            wfsR1 = (WFSRESULT1)Marshal.PtrToStructure(ptr, typeof(WFSRESULT1));
但是之后
             _wfs_idc_status stat1 = new _wfs_idc_status();
            stat1 = (_wfs_idc_status)Marshal.PtrToStructure(wfsR1.lpBuffer, typeof(_wfs_idc_status));
第二行报错"引发类型为“System.ExecutionEngineException”的异常。"。
EnForGrass 2016-12-05
  • 打赏
  • 举报
回复
REQUESTID RequestID; HSERVICE hService这两个真不知道是什么类型的,你自己搞定吧

public struct SYSTEMTIME {
    
    /// WORD->unsigned short
    public ushort wYear;
    
    /// WORD->unsigned short
    public ushort wMonth;
    
    /// WORD->unsigned short
    public ushort wDayOfWeek;
    
    /// WORD->unsigned short
    public ushort wDay;
    
    /// WORD->unsigned short
    public ushort wHour;
    
    /// WORD->unsigned short
    public ushort wMinute;
    
    /// WORD->unsigned short
    public ushort wSecond;
    
    /// WORD->unsigned short
    public ushort wMilliseconds;
}
public struct WFSRESULT {
    
    /// short
    public short RequestID;//假如为short
    
    /// short
    public short hService;////假如为short
    
    /// SYSTEMTIME->_SYSTEMTIME
    public SYSTEMTIME tsTimestamp;
    
    /// HRESULT->LONG->int
    public int hResult;

    public System.IntPtr lpBuffer;
}

public struct WFSIDCSTATUS {
    
    /// WORD->unsigned short
    public ushort fwDevice;
    
    /// WORD->unsigned short
    public ushort fwMedia;
    
    /// WORD->unsigned short
    public ushort fwRetainBin;
    
    /// WORD->unsigned short
    public ushort fwSecurity;
    
    /// USHORT->unsigned short
    public ushort usCards;
    
    /// WORD->unsigned short
    public ushort fwChipPower;
    
    /// LPSTR->CHAR*
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
    public string lpszExtra;
}

    [System.Runtime.InteropServices.DllImportAttribute("XXX.dll", EntryPoint="WFSGetInfo")]
public static extern  int WFSGetInfo(short hService, uint dwCategory, System.IntPtr lpQueryDetails, uint dwTimeOut, ref System.IntPtr lppResult) ;
EnForGrass 2016-12-05
  • 打赏
  • 举报
回复
搞不清楚REQUESTID RequestID; HSERVICE hService; SYSTEMTIME tsTimestamp;这几个是什么

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧