2013-08-30 33 views
1

我必须构建一个SNMP项目以与各种设备进行通信。可悲的是我不能使用任何除了Windows的DLL(mgmtapi.dll,snmpapi.dll,wsnmp32.dll)以外的库。我已经为这些库和所有的THOS库的功能所需要的结构的包装,但周期后:使用.net C编写的SNMP项目的编组错误#

  • SnmpMgrOpen(初始化并获取会话)。
  • 创建SnmpVarBindList(使用SnmpMgrStrToOid,SnmpUtilMemAlloc和其他marshallings)来创建GET请求。
  • SnmpMgrRequest发出请求并填充SnmpVarBindList结构。
  • SnmpMgrClose关闭会话。

当我想看看有什么SnmpVarBindList内SnmpVarBind内使用

Marshal.PtrToStringAnsi(varBind.value.asnValue.text.stream, (int)varBind.value.asnValue.text.length + 1)

,我发现了错误:试图读取或写入保护内存。这通常表明其他内存已损坏。

从标题snmp.h翻译的结构是:

[StructLayout(LayoutKind.Sequential)] 
public struct AsnOctetString 
{ 
    public uint length; 
    public int dynamic; 
    public IntPtr stream; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct AsnObjectIdentifier 
{ 
    public uint idLength; 
    public IntPtr ids; 
} 

[StructLayout(LayoutKind.Explicit)] 
public struct AsnUnion 
{ 
    [FieldOffset(0)] 
    public int number; 
    [FieldOffset(0)] 
    public uint unsigned32; 
    [FieldOffset(0)] 
    public ulong counter64; 
    [FieldOffset(0)] 
    public AsnOctetString text; 
    [FieldOffset(0)] 
    public AsnOctetString bits; 
    [FieldOffset(0)] 
    public AsnObjectIdentifier objectID; 
    [FieldOffset(0)] 
    public AsnOctetString sequence; 
    [FieldOffset(0)] 
    public AsnOctetString address; 
    [FieldOffset(0)] 
    public uint counter; 
    [FieldOffset(0)] 
    public uint gauge; 
    [FieldOffset(0)] 
    public uint ticks; 
    [FieldOffset(0)] 
    public AsnOctetString arbitrary; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct AsnAny 
{ 
    public byte asnType; 
    public AsnUnion asnValue; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct SnmpVarBind 
{ 
    public AsnObjectIdentifier name; 
    public AsnAny value; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct SnmpVarBindList 
{ 
    public IntPtr list; 
    public uint len; 
} 

有什么想法?我可以把你想要/需要的代码。

回答

0

我知道这个答案很晚,但最近我遇到了SNMP API的编组问题。我曾假设这些结构是按字节边界打包的,但这是错误的。如果你看看Snmp.h,你会看到#include <pshpack4.h>,它打开4字节的边界。这意味着现场补偿是不同的。这就是我的AsnAny长相如下:

[StructLayout(LayoutKind.Explicit)] 
    private struct AsnAny 
    { 
     [FieldOffset(0)] 
     public readonly byte Type; 

     [FieldOffset(4)] 
     public readonly Int32 Number; 

     [FieldOffset(4)] 
     public readonly UInt32 Unsigned32; 

     [FieldOffset(4)] 
     public readonly UInt64 Counter64; 

     [FieldOffset(4)] 
     public readonly AsnOctetString String; 

     [FieldOffset(4)] 
     public readonly AsnOctetString Bits; 

     [FieldOffset(4)] 
     public readonly AsnObjectIdentifier Object; 

     [FieldOffset(4)] 
     public readonly AsnOctetString Sequence; 

     [FieldOffset(4)] 
     public readonly AsnOctetString IPAddress; 

     [FieldOffset(4)] 
     public readonly UInt32 Counter32; 

     [FieldOffset(4)] 
     public readonly UInt32 Gauge32; 

     [FieldOffset(4)] 
     public readonly UInt32 Ticks; 

     [FieldOffset(4)] 
     public readonly AsnOctetString Arbitrary; 
    }