我是OCaml的新手,并且想尝试使用pcap作为一种入门方式,但是,似乎没有一个维护的库.在看了一本很棒的真实世界OCaml书之后,我想我会给写一个有约束力的书.
这是(差)代码片段:
open Ctypes
open Foreign
open PosixTypes
let char_ptr = " "
let pcap_lookupdev = foreign "pcap_lookupdev" (string @-> returning string_opt)
let result = pcap_lookupdev char_ptr
let test2 =
match result with
| None -> char_ptr
| Some str -> str
;;
print_string test2;;
Run Code Online (Sandbox Code Playgroud)
pcap_lookupdev函数返回包含设备名称的字符串或空指针.这一点似乎工作得很好(虽然我知道我的代码很难说是惯用的).
在C中编写时,需要提供一个字符数组来保存任何错误消息.因此,如果返回空指针,则应该以此字符数组中保留的原因失败.此字符数组应为"PCAP_ERRBUF_SIZE"长.但是我无法弄清楚两件事:
最感谢任何帮助:)
1)将#ifdef'd符号转换为OCaml的最简单方法是编写一个C程序,输出一个带有这些符号值的单独模块.然后,当您需要符号时,只需在绑定中使用此模块.您可以在此处找到此方法的示例.
对于2)我会说ctypes string有点具有欺骗性,因为它似乎不是双向的,也就是你应该只使用它const char *或返回类型.在这种情况下,您需要使用字符数组,然后将其转换为字符串(char_array_as_string我认为此函数应添加到ctypes ).这是完整的示例,请注意,在ctypes的未来版本中,Array模块将其名称更改为CArray:
(* Compile with: ocamlfind ocamlopt -package ctypes.foreign -linkpkg -cclib -lpcap \
-o test.native test.ml *)
open Ctypes;;
open Foreign;;
module Pcap : sig
val lookupdev : unit -> [ `Ok of string | `Error of string ]
end = struct
let errbuf_size = 256 (* N.B. This should not be hardcoded, see 1) above *)
let char_array_as_string a =
let len = Array.length a in
let b = Buffer.create len in
try
for i = 0 to len -1 do
let c = Array.get a i in
if c = '\x00' then raise Exit else Buffer.add_char b c
done;
Buffer.contents b
with Exit -> Buffer.contents b
let lookupdev =
foreign "pcap_lookupdev" (ptr char @-> returning string_opt)
let lookupdev () =
let err = Array.make char ~initial:'\x00' errbuf_size in
match lookupdev (Array.start err) with
| None -> `Error (char_array_as_string err)
| Some dev -> `Ok dev
end
let test () = match Pcap.lookupdev () with
| `Ok dev -> Printf.printf "dev: %s\n" dev
| `Error err -> Printf.printf "error: %s\n" err
let () = test ()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
552 次 |
| 最近记录: |