c#struct to IntPtr给出了System.AccessViolationException

时间:2017-01-27 13:15:57

标签: c# pointers

我使用的是具有功能定义的DLL:

public J2534Err PassThruIoctl(int channelId, int ioctlID, IntPtr input, IntPtr output)

有一个有效的vb程序:

Public Type SCONFIG_LIST
    NumOfParams As Long
    ConfigPtr As Long
End Type
Public Type SCONFIG
    Parameter As Long
    Value As Long
End Type

Dim sCfg As SCONFIG, sCfgList As SCONFIG_LIST
sCfg.Parameter = J1962_PINS
sCfg.Value = J2534Prot(lProtIndex).PinsValue
sCfgList.NumOfParams = 1
sCfgList.ConfigPtr = VarPtr(sCfg) lResult = PassThruIoctl(J2534Boxes(lSelectedBox).Channel(lProtIndex).ChID, SET_CONFIG, sCfgList, ByVal 0&)

我想在C#中调用此函数

以下编译,但提供System.AccessViolationException

private IntPtr objectToIntptr(object o)
{
     GCHandle handle = GCHandle.Alloc(o, GCHandleType.Pinned);
     return handle.AddrOfPinnedObject();
}

SConfig sCfg;
SConfigList sCfgList = new SConfigList();

sCfg.Parameter = ConfigParameter.J1962_PINS;
sCfg.Value = 0xff;

sCfgList.Count = 1;
sCfgList.ListPtr = objectToIntptr(sCfg);

m_status = m_j2534Interface.PassThruIoctl(m_channelId, (int)Ioctl.SET_CONFIG, objectToIntptr(sCfg), IntPtr.Zero);

还尝试了一些使用马歇尔发现的代码片段。 但它要么不会编译,要么在AccessViolationException上出错。

1 个答案:

答案 0 :(得分:0)

m_status = m_j2534Interface.PassThruIoctl(m_channelId, (int)Ioctl.SET_CONFIG, objectToIntptr(sCfg), IntPtr.Zero);

应该是

m_status = m_j2534Interface.PassThruIoctl(m_channelId, (int)Ioctl.SET_CONFIG, objectToIntptr(sCfgList), IntPtr.Zero);

我传递了错误的变种.. 寻找小时,发布后10分钟: - (

@dan

  public struct SConfigList
{
    public int Count { get; set; }

    public IntPtr ListPtr { get; set; }

    public List<SConfig> GetList()
    {
        if (ListPtr == IntPtr.Zero)
            return new List<SConfig>();
        return ListPtr.AsList<SConfig>(Count);
    }
}

我猜我必须有一个更清洁的方法,我正在做的事情。