2017-09-09 9 views
2

Ruby FFI에서 완벽하게 작동하는 많은 녹 기능이 있습니다. 그러나 free_array 메서드를 만드는 두 가지 다른 사이트의 지침에 따라 링크 된 라이브러리에서 메서드를 사용할 수 없습니다.실망시키지 않는 라이브러리 extern FFI

이 예제는 Ruby에서 반환 된 String을 해제하는 작업 예제입니다.

use libc::c_char; 
use std::ffi::CString; 

#[no_mangle] 
pub extern "C" fn free_string(s: *mut c_char) { 
    unsafe { 
    if s.is_null() { return } 
    CString::from_raw(s) 
    }; 
} 

그리고 여기에 배열의 메모리를 확보하는 두 가지 시도가 있습니다.

use std::mem::transmute; 
use ruby_array::RubyArray; 

#[no_mangle] 
pub extern "C" fn free_array(ra: *mut RubyArray) { 
    let _ra: Box<RubyArray> = unsafe{ transmute(ra) }; 
} 

// OR 

#[no_mangle] 
pub extern "C" fn free_array(ptr: *mut RubyArray) { 
    if ptr.is_null() { return } 
    unsafe { Box::from_raw(ptr); } 
} 

이 오류가 발생합니다

Function 'free_array' not found in [/libfaster_path.so] (FFI::NotFoundError) 

여기 내가 사용 구조체의 어느 녹에서 루비로 완벽하게 생성됩니다.

use libc; 
use std::mem; 

#[repr(C)] 
pub struct RubyArray { 
    len: libc::size_t, 
    data: *const libc::c_void, 
} 

impl RubyArray { 
    #[allow(dead_code)] 
    pub fn from_vec<T>(vec: Vec<T>) -> RubyArray { 
    let array = RubyArray { 
     data: vec.as_ptr() as *const libc::c_void, 
     len: vec.len() as libc::size_t 
    }; 
    mem::forget(vec); 
    array 
    } 
} 

하지만 문제가되지 않으므로 관련이 없습니다. 문제는 FFI가 읽을 라이브러리 출력에서 ​​메소드를 사용할 수 없다는 것입니다. 이게 뭐가 잘못 됐어? 녹이 행복하고 나는 비슷한 방식으로 많은 다른 방법을 저술했습니다. 무엇이 .so 파일에 없습니까?

파일은 src/lib.rspub mod과 함께 포함되어 있으므로 아무 문제가 없습니다. 다른 작업 방법과 같습니다.

나중에 더 자세한 구현 정보가 담긴 블로그를 게시하고 관심있는 사람들을 위해 아래의 댓글 섹션에 대한 링크를 추가하겠습니다.


마이너 업데이트

나는이 녹에 문제가 꽤 확신한다. 필자는 Ruby의 Fiddle과 FFI를 사용하여이 방법이 다른 방법으로 사용될 수 없는지 확인했습니다.

바이너리를 바르고 이진 파일에 free_array 메서드가있는 텍스트를 발견했지만 FFI가 올바르게 컴파일하지 못했습니다.

+0

Rust 's Github https://github.com/rust-lang/rust/issues/44459에서 문제를 열었습니다. –

답변

0

제공된 정보로는 문제를 디버그하기에 충분하지 않았습니다. 실제 문제는 릴리스 소스에서 디버깅 소스로 변경되었고이를 반영하기 위해 FFI 링크 라이브러리 폴더를 업데이트하지 않았기 때문입니다. 그래서 코드는 계속 가리키고 오래된 lib를 가리 킵니다.