我使用的是具有功能定义的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上出错。
答案 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);
}
}
我猜我必须有一个更清洁的方法,我正在做的事情。