You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#调用libnl的nla_parse时struct nlattr双指针的正确封送问题

核心错误点

原生nla_parse的第一个参数struct nlattr **tb是nlattr类型的指针数组,数组中每个元素存储的是指向实际nlattr结构体的指针,而不是存储nlattr结构体本身的数组,你当前的申请逻辑完全不符合预期:

  • 你申请的内存大小为 sizeof(nlattr) * (NL80211_ATTR_MAX +1),每个元素仅占用4字节(两个ushort的总长度)
  • 实际需要的内存大小为 IntPtr.Size * (NL80211_ATTR_MAX +1),32位系统下每个元素占4字节、64位系统下每个元素占8字节,64位场景下你申请的内存只有实际需要的一半,nla_parse写入时就会越界破坏堆内存,触发malloc(): memory corruption报错。

修复方案

方案1(推荐,不需要手动管理非托管内存)

直接修改nla_parse的extern签名,让.NET运行时自动处理指针数组的封送:

// 修正后的extern签名,[Out]特性指示运行时把原生写入的数组内容封送回托管层
public static extern int nla_parse([Out] IntPtr[] tb, int maxtype, IntPtr head, int len, IntPtr policy);

调用逻辑简化为:

var NL80211_ATTR_MAX = 305;
// 直接声明托管的指针数组即可
IntPtr[] tb = new IntPtr[NL80211_ATTR_MAX + 1];
var returnCode = NetlinkDemo.nla_parse(tb, NL80211_ATTR_MAX, gnlMsgAttrDataHeaderPtr, gnlMsgAttrLength, IntPtr.Zero);

// 后续读取属性示例
int targetAttrType = 10; // 替换为你要读取的属性类型
if (tb[targetAttrType] != IntPtr.Zero)
{
    nlattr attr = Marshal.PtrToStructure<nlattr>(tb[targetAttrType]);
    // 处理属性逻辑
}

方案2(保留手动申请非托管内存的写法)

修改内存申请的大小计算逻辑:

var NL80211_ATTR_MAX = 305;
// 按指针长度计算数组总大小
var nlAttrPtrArraySize = IntPtr.Size * (NL80211_ATTR_MAX + 1);
var nlAttrPtrArrayPtr = Marshal.AllocHGlobal(nlAttrPtrArraySize);

// 调用nla_parse
var returnCode = NetlinkDemo.nla_parse(nlAttrPtrArrayPtr, NL80211_ATTR_MAX, gnlMsgAttrDataHeaderPtr, gnlMsgAttrLength, IntPtr.Zero);

// 后续读取属性示例
int targetAttrType = 10;
// 按指针偏移读取对应位置的指针值
IntPtr attrPtr = Marshal.ReadIntPtr(nlAttrPtrArrayPtr, targetAttrType * IntPtr.Size);
if (attrPtr != IntPtr.Zero)
{
    nlattr attr = Marshal.PtrToStructure<nlattr>(attrPtr);
    // 处理属性逻辑
}

// 一定要记得释放手动申请的非托管内存,避免泄漏
Marshal.FreeHGlobal(nlAttrPtrArrayPtr);

额外检查项

如果修改后仍有问题,再排查两个点:

  • 确认gnlMsgAttrLength是通过genlmsg_attrlen接口计算得到的,不要手动硬算长度,长度错误也会导致nla_parse越界访问
  • 确认你用到的nlmsghdr、genlmsghdr等其他Netlink相关结构体的布局、字段顺序、字段类型和原生C定义完全一致,结构体字段映射错误也会导致指针计算偏移错误

内容的提问来源于stack exchange,提问作者Veverke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 22:15:04