2016-09-24 1 views
0

this definition in the ncurses-rs crate을 감안할 때 :왜 * mut i8이 ncurses-rs의 WINDOW 유형에 사용됩니까?

pub type WINDOW = *mut i8; 

usage of WINDOW :

pub fn newwin(_:c_int,_:c_int,_:c_int,_:c_int) -> WINDOW; 

및 구현, ncurses의에서 C 라이브러리 (1, 2, 3) : 왜 유형이

// 1: 
typedef struct _win_st WINDOW; 
// 2: 
struct _win_st { 
    /* lots of fields... */ 
}; 
// 3: 
(WINDOW *) newwin (int,int,int,int); 

입니다 WINDOW*mut i8?

나는 분명히 정확하지 않은 C char에 대한 포인터로 이것을 읽고있다. Custer를 Rust에서 구현하지 않는다면 단순히 포인터가 타입 i8이라고 말하는 것이 가장 좋습니다. 그것이 어떤 유형인지는 중요하지 않습니까?

+1

'WINDOW'의 내용이 중요하지 않고 'WINDOW'가 항상 포인터를 통해 조작되기 때문에 이것은'void *'(Rust에는 없다)와 유사합니다. – mcarton

+2

@mcarton 같은 소스 파일에서 조금 더 높은'c_void' 타입을 의미합니다 (https://github.com/jeaye/ncurses-rs/blob/59fbbc6456dcd87d29a7761576723dab0c08986b/src/ll.rs# L14)?^_^ – Shepmaster

+0

@Shepmaster 그래서 저와 달리 저자는'c_void'에 대해 알고있었습니다 : p. 어쨌든 새로운 전용 유형이 더 좋을 것입니다. 항상 좋은 대답입니다. – mcarton

답변

6

해당 프로젝트의 작성자가 과거를 산책하지 않으면 권한있는 답변을 얻을 수 없습니다.

mcarton points out으로, 일반적으로 C에서 불투명 구조체에 대한 참조를 나타 내기 위해 void *에 도달합니다. 작성자도 쉽게 할 수 있습니다.

pub type WINDOW = *mut c_void; 

이 변경으로 코드는 여전히 컴파일됩니다.

그러나 더 나은 옵션이 있습니다. the documentation says으로 :

녹에서이 작업을 수행하기 위해,이 enum와 우리 자신의 불투명 한 유형을 만들 수 있습니다 :

pub enum Foo {} 
pub enum Bar {} 

extern "C" { 
    pub fn foo(arg: *mut Foo); 
    pub fn bar(arg: *mut Bar); 
} 

을 전혀 변형이있는 enum를 사용하여, 우리가 불투명 한 유형을 생성하는 우리는 할 수 없습니다 변종이 없으므로 인스턴스화하십시오. 그러나 FooBar 유형이 서로 다르므로 두 유형간에 유형 안전성이 적용되므로 Foo에서 bar()으로의 포인터를 우연히 전달할 수 없습니다.

pub enum Window {} 
pub type WINDOW = *mut Window; 

다시 라이브러리가 여전히 변화 컴파일 :처럼이 경우

, 그것을 볼 수 있었다.

+0

와우, 나는 완전히 내 질문에 직접 대답하는 문서의 그 부분을 놓쳤다. :) 고마워. – mjhoy

관련 문제