Skip to content

Instantly share code, notes, and snippets.

@hkoba
Created August 7, 2019 10:57
Show Gist options
  • Save hkoba/10057bc8b18ce7a349cd6136d1bcb090 to your computer and use it in GitHub Desktop.
Save hkoba/10057bc8b18ce7a349cd6136d1bcb090 to your computer and use it in GitHub Desktop.
An example of rust ffi to call perl_parse()
// cargo run -- -le 'use strict; $x'
use std::ptr;
use std::ffi::CString; // C に渡す文字列
// use std::ffi::CStr; // for C から返された文字列
use std::os::raw::{c_char, c_int /*, c_void*/, c_schar};
enum PerlInterpreter {}
enum XsinitT {}
#[link(name = "perl")]
extern "C" {
fn perl_alloc() -> *mut PerlInterpreter;
fn perl_construct(my_perl: *mut PerlInterpreter);
fn perl_parse(
my_perl: *mut PerlInterpreter,
xsinit: *const XsinitT,
argc: c_int,
argv: *const *const c_schar,
env: *const *const c_schar,
) -> c_int;
fn perl_destruct(my_perl: *mut PerlInterpreter) -> c_int;
}
fn main() {
// https://stackoverflow.com/questions/34379641/how-do-i-convert-rust-args-into-the-argc-and-argv-c-equivalents
let args = std::env::args().map(|arg| CString::new(arg).unwrap() ).collect::<Vec<CString>>();
// convert the strings to raw pointers
let c_args = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<*const c_char>>();
let my_perl = unsafe {perl_alloc()};
unsafe {perl_construct(my_perl)};
// println!("c_args[0] = 0x{:x}\nc_args[1] = 0x{:x}"
// , c_args[0] as usize, c_args[1] as usize);
let _rc = unsafe {
perl_parse(
my_perl,
ptr::null(),
c_args.len() as c_int,
c_args.as_ptr(),
ptr::null()
);
};
unsafe {perl_destruct(my_perl)};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment