2017-04-11 2 views
3

내가 C 코드에서 수행하고자하는 내용은 다음과 같습니다녹 색 FFI를 사용할 때 불투명 C 구조체를 초기화하는 방법은 무엇입니까? 여기

#include <some_lib.h> 
int main() { 
    some_lib_struct_t x; 
    some_lib_func(&x); 
} 

가 어떻게 녹에있는 라이브러리를 사용해야합니까? 여기에 지금까지있어 무엇 :

extern crate libc; 

struct some_lib_struct_t; 
#[link(name="some_lib")] 
extern { 
    fn some_lib_func(x: *mut some_lib_struct_t); 
} 

fn main() { 
    let mut x: some_lib_struct_t; 
    unsafe { 
     some_lib_func(&mut x); 
    } 
} 

I 컴파일 (그리 놀라 울) 오류를 얻을 : use of possibly uninitialized `x`은.

편집 Shepmaster의 답변을 읽은 후 나는 라이브러리의 헤더에 가까워 보였다. 그들이 말했듯이, some_lib_struct_tactual_lib_struct_t에 대한 포인터의 typedef 일뿐입니다. 다음과 같이 변경했습니다.

extern crate libc; 

struct actual_lib_struct_t; 
type some_lib_type_t = *mut actual_lib_struct_t; 

#[link(name="some_lib")] 
extern { 
    fn some_lib_func(x: *mut some_lib_type_t); 
} 

fn main() { 
    let mut x: some_lib_type_t; 
    unsafe { 
     x = std::mem::uninitialized(); 
     some_lib_func(&mut x); 
    } 
} 

그리고 작동합니다! 나는 그러나 경고 found zero-size struct in foreign module, consider adding a member to this struct, #[warn(improper_ctypes)] on by default을 얻는다. 이게 내가 억압 할 수있는 것입니까, 아니면 뭔가를 바꿀 필요가 있습니까?

unsafe { 
    let mut x: some_lib_struct_t = std::mem::uninitialized(); 
    some_lib_func(&mut x); 
} 

당신에게 some_lib_func 완전히 확인해야합니다 :

let mut x: some_lib_struct_t = some_lib_struct_t; 
unsafe { 
    some_lib_func(&mut x); 
} 

C 코드에 가장 가까운 아날로그 mem::uninitialized가 사용하는 것입니다

답변

5

가장 안전한 대답은 구조체를 직접 초기화하는 것입니다 구조체의 모든 멤버를 초기화합니다. 그렇지 않으면 안전하지 않은 부분이 unsafe 블록 외부로 유출됩니다.

"구조체의 멤버"라고 말하면 코드가 원하는대로 작동하지 않을 수도 있습니다. some_lib_struct_t을 크기가 0 인 것으로 정의했습니다. 즉, 스택 공간이 할당되지 않으며 C 코드가 기대하는 바가 아니기 때문입니다.

Rust에서 C 구조체의 정의를 미러링하여 적절한 크기, 패딩 및 정렬을 할당 할 수 있어야합니다. 일반적으로 이는 repr(C)을 사용하는 것을 의미합니다. 나는 그것을 사용하여 작업 가지고

+0

:

많은 경우, C 라이브러리는 항상 불투명 타입에 대한 포인터를 반환하여 내부 구조체 표현을 노출되지 않도록 mem :: uninitialized(). 하지만 컴파일러로부터 경고를받습니다. 더 많은 정보로 질문을 업데이트했습니다. – EFTH

+0

@EFTH 이미 언급했습니다. "제로 사이즈 (zero size)"에 대한 제 대답의 부분을보십시오. * 불투명 포인터 *가있는 경우 링크 된 3 개의 질문을 참조하십시오. – Shepmaster