将 C 结构体转换为 FFI::Struct

发布于 2024-09-27 15:36:41 字数 1064 浏览 0 评论 0原文

我在 FFI 中的 pcap 库中设置结构时遇到困难。

结构:

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 作为名称。

I am having difficulty setting up a struct from the pcap library in FFI.

Struct:

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

The relevant Ruby code

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

Above attached function definition

int    pcap_findalldevs(pcap_if_t **, char *)

The test code(run as 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]

The output is

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)

The offsets look right to me but my C is very rusty. I was expecting 2 devices: lo and eth0 as names.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏の忆 2024-10-04 15:36:41

发帖速度慢:
代码应该是这样的:

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

Slow post:
Code should go like this:

ptr = FFI::MemoryPointer.new Pcap::Pcap_if.size
res = Pcap.pcap_findalldevs ptr,tmp
devs = Pcap::Pcap_if.new ptr
下雨或天晴 2024-10-04 15:36:41

我找到了解决方案。 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;
 }

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

I found the solution. FFI can't deal with pcap_if_t **. I wrote a C function to return just an array of structs.

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

I still need to handle error cases, but this does work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文