2010-10-18 71 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