2017-01-27 4 views
0

Я использую DLL, которая имеет определение функции:с # структура в IntPtr дает System.AccessViolationException

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

Существует программа рабочего В.Б:

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); 

Также попробовал некоторые фрагменты кода, которые я нашел, используя marshall. Но он либо не будет компилироваться, либо ошибки в AccessViolationException.

+0

1) вам не нужно явно указывать P/Invoke; 2) вы не показали нам, как вы определили 'SConfigList', предоставите [mcve]. –

ответ

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); 
    } 
} 

Я предполагаю, что должен быть более чистый способ сделать, что я делаю.