2010-10-18 109 views
1

我无法从FFI中的pcap库设置结构。将C结构转换为FFI :: Struct

STRUCT:

struct pcap_if { 
struct pcap_if *next; 
char *name;   
char *description;  
struct pcap_addr *addresses; 
bpf_u_int32 flags;  
}; 

相关Ruby代码

module Pcap 
extend FFI::Library 
ffi_lib 'pcap' 

attach_function :pcap_findalldevs,[:pointer,:string],:int 

class Pcap_if < FFI::Struct 
layout :next,:pointer, 
    :name,:string, 
    :description,:string, 
    :pcap_addr,:pointer, 
    :flags,:int 
end 
end 

上方安装函数定义

int pcap_findalldevs(pcap_if_t **, char *) 

测试代码(作为root运行)

tmp='' 
ptr = FFI::MemoryPointer.new :pointer 
res = Pcap.pcap_findalldevs ptr,tmp 
devs = Pcap::Pcap_if.new ptr 
puts res 
puts devs.offsets 
puts devs[:name] 

输出是

0 #pcap_findalldevs return success 
next 
0 
name 
4 
description 
8 
pcap_addr 
12 
flags 
16 
pcap.rb:29:in `[]': Memory access offset=4 size=4 is out of bounds (IndexError) 

偏移量看我的权利,但我的C是非常生疏。我期待2个设备:lo和eth0作为名称。

回答

0

我找到了解决方案。 FFI无法处理pcap_if_t **。我写了一个C函数来返回一个结构数组。

pcap_if_t* find_devs() 
{ 
    pcap_if_t *devs; 
    char errbuf[PCAP_ERRBUF_SIZE]; 
    int res; 
    res=pcap_findalldevs(&devs, errbuf); 
    return devs; 
} 

我仍然需要处理错误情况,但这确实有效。

1

慢后: 代码应该是这样的:

ptr = FFI::MemoryPointer.new Pcap::Pcap_if.size 
res = Pcap.pcap_findalldevs ptr,tmp 
devs = Pcap::Pcap_if.new ptr