GetIpForwardTable 在 WIndows CE 上使用 PInvoke 返回垃圾
我有以下问题。我在 Windows CE .NET 托管项目中为 GetIpForwardTable 函数创建了一个 PInvoke。当我调用函数in返回结果时,但结果与route命令返回的结果不同。表中有更多条目,Mask 和 Destination 已更改位置,NextHop 始终设置为 0.0.0.0
这是该类(需要调用 IPForwardEntry.GetIpForwardTable())。
public class IPForwardEntry
{
public enum ForwardType
{
Other = 1,
Invalid = 2,
Direct = 3,
Indirect = 4
}
public enum ForwardProtocol
{
Other = 1,
Local = 2,
NetMGMT = 3,
ICMP = 4,
EGP = 5,
GGP = 6,
Hello = 7,
RIP = 8,
IS_IS = 9,
ES_IS = 10,
CISCO = 11,
BBN = 12,
OSPF = 13,
BGP = 14,
NT_AUTOSTATIC = 10002,
NT_STATIC = 10006,
NT_STATIC_NON_DOD = 10007
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_IPFORWARDROW
{
public uint dwForwardDest;
public uint dwForwardMask;
public int dwForwardPolicy;
public uint dwForwardNextHop;
public int dwForwardIfIndex;
public ForwardType dwForwardType;
public ForwardProtocol dwForwardProto;
public int dwForwardAge;
public int dwForwardNextHopAS;
public int dwForwardMetric1;
public int dwForwardMetric2;
public int dwForwardMetric3;
public int dwForwardMetric4;
public int dwForwardMetric5;
}
private IPForwardEntry(MIB_IPFORWARDROW forwardRow)
{
myForwardRow = forwardRow;
}
private MIB_IPFORWARDROW myForwardRow;
private const int NO_ERROR = 0;
[DllImport("Iphlpapi.dll")]
private static extern int CreateIpForwardEntry(MIB_IPFORWARDROW[] pRoute);
[DllImport("Iphlpapi.dll")]
private static extern int GetIpForwardTable(MIB_IPFORWARDROW[] pIpForwardTable, ref long pdwSize, bool bOrder);
public static IPForwardEntry[] GetIpForwardTable()
{
long tableSize = 0;
GetIpForwardTable(null, ref tableSize, true);
MIB_IPFORWARDROW[] forwardTable = new MIB_IPFORWARDROW[tableSize / Marshal.SizeOf(typeof(MIB_IPFORWARDROW)) + 1];
long tableSizeOld = tableSize;
if (GetIpForwardTable(forwardTable, ref tableSize, false) != NO_ERROR)
throw new SystemException();
if (tableSizeOld != tableSize)
throw new SystemException();
IPForwardEntry[] result = new IPForwardEntry[forwardTable.Length];
for (int i = 0; i < forwardTable.Length; i++)
result[i] = new IPForwardEntry(forwardTable[i]);
return result;
}
#region members
public IPAddress FordwardDestination
{
get
{
return new IPAddress(myForwardRow.dwForwardDest);
}
set
{
myForwardRow.dwForwardDest = (uint) value.Address;
}
}
public IPAddress ForwardMask
{
get
{
return new IPAddress(myForwardRow.dwForwardMask);
}
set
{
myForwardRow.dwForwardMask = (uint) value.Address;
}
}
public int ForwardPolicy
{
get
{
return myForwardRow.dwForwardPolicy;
}
set
{
myForwardRow.dwForwardPolicy = value;
}
}
public IPAddress ForwardNextHop
{
get
{
return new IPAddress(myForwardRow.dwForwardNextHop);
}
set
{
myForwardRow.dwForwardNextHop = (uint) value.Address;
}
}
public int ForwardInterfaceIndex
{
get
{
return myForwardRow.dwForwardIfIndex;
}
set
{
myForwardRow.dwForwardIfIndex = value;
}
}
public ForwardType ForwrdType
{
get
{
return myForwardRow.dwForwardType;
}
set
{
myForwardRow.dwForwardType = value;
}
}
public ForwardProtocol Protocol
{
get
{
return myForwardRow.dwForwardProto;
}
set
{
myForwardRow.dwForwardProto = value;
}
}
public int ForwardAge
{
get
{
return myForwardRow.dwForwardAge;
}
set
{
myForwardRow.dwForwardAge = value;
}
}
public int ForwardNextHopAS
{
get
{
return myForwardRow.dwForwardNextHopAS;
}
set
{
myForwardRow.dwForwardNextHopAS = value;
}
}
public int ForwardMetric1
{
get
{
return myForwardRow.dwForwardMetric1;
}
set
{
myForwardRow.dwForwardMetric1 = value;
}
}
public int ForwardMetric2
{
get
{
return myForwardRow.dwForwardMetric2;
}
set
{
myForwardRow.dwForwardMetric2 = value;
}
}
public int ForwardMetric3
{
get
{
return myForwardRow.dwForwardMetric3;
}
set
{
myForwardRow.dwForwardMetric3 = value;
}
}
public int ForwardMetric4
{
get
{
return myForwardRow.dwForwardMetric4;
}
set
{
myForwardRow.dwForwardMetric4 = value;
}
}
public int ForwardMetric5
{
get
{
return myForwardRow.dwForwardMetric5;
}
set
{
myForwardRow.dwForwardMetric5 = value;
}
}
#endregion
}
I have a following problem. I created a PInvoke in a Windows CE .NET managed project for GetIpForwardTable function. When I call the function in returns the result, but the results are different from the result returned by the route command. There are more entries in the table, Mask and Destination changed places and NextHop is always set to 0.0.0.0
Here is the class (one needs to call IPForwardEntry.GetIpForwardTable()).
public class IPForwardEntry
{
public enum ForwardType
{
Other = 1,
Invalid = 2,
Direct = 3,
Indirect = 4
}
public enum ForwardProtocol
{
Other = 1,
Local = 2,
NetMGMT = 3,
ICMP = 4,
EGP = 5,
GGP = 6,
Hello = 7,
RIP = 8,
IS_IS = 9,
ES_IS = 10,
CISCO = 11,
BBN = 12,
OSPF = 13,
BGP = 14,
NT_AUTOSTATIC = 10002,
NT_STATIC = 10006,
NT_STATIC_NON_DOD = 10007
}
[StructLayout(LayoutKind.Sequential)]
public struct MIB_IPFORWARDROW
{
public uint dwForwardDest;
public uint dwForwardMask;
public int dwForwardPolicy;
public uint dwForwardNextHop;
public int dwForwardIfIndex;
public ForwardType dwForwardType;
public ForwardProtocol dwForwardProto;
public int dwForwardAge;
public int dwForwardNextHopAS;
public int dwForwardMetric1;
public int dwForwardMetric2;
public int dwForwardMetric3;
public int dwForwardMetric4;
public int dwForwardMetric5;
}
private IPForwardEntry(MIB_IPFORWARDROW forwardRow)
{
myForwardRow = forwardRow;
}
private MIB_IPFORWARDROW myForwardRow;
private const int NO_ERROR = 0;
[DllImport("Iphlpapi.dll")]
private static extern int CreateIpForwardEntry(MIB_IPFORWARDROW[] pRoute);
[DllImport("Iphlpapi.dll")]
private static extern int GetIpForwardTable(MIB_IPFORWARDROW[] pIpForwardTable, ref long pdwSize, bool bOrder);
public static IPForwardEntry[] GetIpForwardTable()
{
long tableSize = 0;
GetIpForwardTable(null, ref tableSize, true);
MIB_IPFORWARDROW[] forwardTable = new MIB_IPFORWARDROW[tableSize / Marshal.SizeOf(typeof(MIB_IPFORWARDROW)) + 1];
long tableSizeOld = tableSize;
if (GetIpForwardTable(forwardTable, ref tableSize, false) != NO_ERROR)
throw new SystemException();
if (tableSizeOld != tableSize)
throw new SystemException();
IPForwardEntry[] result = new IPForwardEntry[forwardTable.Length];
for (int i = 0; i < forwardTable.Length; i++)
result[i] = new IPForwardEntry(forwardTable[i]);
return result;
}
#region members
public IPAddress FordwardDestination
{
get
{
return new IPAddress(myForwardRow.dwForwardDest);
}
set
{
myForwardRow.dwForwardDest = (uint) value.Address;
}
}
public IPAddress ForwardMask
{
get
{
return new IPAddress(myForwardRow.dwForwardMask);
}
set
{
myForwardRow.dwForwardMask = (uint) value.Address;
}
}
public int ForwardPolicy
{
get
{
return myForwardRow.dwForwardPolicy;
}
set
{
myForwardRow.dwForwardPolicy = value;
}
}
public IPAddress ForwardNextHop
{
get
{
return new IPAddress(myForwardRow.dwForwardNextHop);
}
set
{
myForwardRow.dwForwardNextHop = (uint) value.Address;
}
}
public int ForwardInterfaceIndex
{
get
{
return myForwardRow.dwForwardIfIndex;
}
set
{
myForwardRow.dwForwardIfIndex = value;
}
}
public ForwardType ForwrdType
{
get
{
return myForwardRow.dwForwardType;
}
set
{
myForwardRow.dwForwardType = value;
}
}
public ForwardProtocol Protocol
{
get
{
return myForwardRow.dwForwardProto;
}
set
{
myForwardRow.dwForwardProto = value;
}
}
public int ForwardAge
{
get
{
return myForwardRow.dwForwardAge;
}
set
{
myForwardRow.dwForwardAge = value;
}
}
public int ForwardNextHopAS
{
get
{
return myForwardRow.dwForwardNextHopAS;
}
set
{
myForwardRow.dwForwardNextHopAS = value;
}
}
public int ForwardMetric1
{
get
{
return myForwardRow.dwForwardMetric1;
}
set
{
myForwardRow.dwForwardMetric1 = value;
}
}
public int ForwardMetric2
{
get
{
return myForwardRow.dwForwardMetric2;
}
set
{
myForwardRow.dwForwardMetric2 = value;
}
}
public int ForwardMetric3
{
get
{
return myForwardRow.dwForwardMetric3;
}
set
{
myForwardRow.dwForwardMetric3 = value;
}
}
public int ForwardMetric4
{
get
{
return myForwardRow.dwForwardMetric4;
}
set
{
myForwardRow.dwForwardMetric4 = value;
}
}
public int ForwardMetric5
{
get
{
return myForwardRow.dwForwardMetric5;
}
set
{
myForwardRow.dwForwardMetric5 = value;
}
}
#endregion
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
GetIpForwardTable 不返回 MIB_IPFORWARDROW 对象数组,它返回一个 MIB_IPFORWARDTABLE,其中包含行数组和数字。所以这至少是一个问题。可能还有其他的,因为这不是一个简单的用于封送的 P/Invoke 集。
无论如何,我已经在 Smart 中实现了所有这些代码设备框架,特别是在 OpenNETCF 中.Net.NetworkInformation.IPRoutingTable 类
GetIpForwardTable doesn't return an array of MIB_IPFORWARDROW objects, it returns a MIB_IPFORWARDTABLE, that contains an array of rows and the number. So that's at least one issue. There are likely others as this is not a straightforward P/Invoke set for marshaling.
For what it's worth, I've already implemented all of this code in the Smart Device Framework, specifically in the OpenNETCF.Net.NetworkInformation.IPRoutingTable class
我不知道这个函数是如何工作的,但是下面的代码看起来很可疑。
new MIB_IPFORWARDROW[tableSize / Marshal.SizeOf(typeof(MIB_IPFORWARDROW)) + 1]
为什么要除以
sizeof
?I dont know how the function works, but the following looks very suspicious.
new MIB_IPFORWARDROW[tableSize / Marshal.SizeOf(typeof(MIB_IPFORWARDROW)) + 1]
Why are you dividing by the
sizeof
?