2017-11-02 5 views
3

슬라이스에 대한 참조로 Go에서 Rust로 작성된 일부 외부 함수를 호출하려고합니다.슬라이스를 매개 변수로 사용하여 이동에서 녹 기능을 호출하려면 어떻게해야합니까?

나는 다음과 같은 녹 코드가 : 지금 이동에서이 함수를 호출 할 수 있습니다

#IFNDEF BOGUSLIB_H 
#DEFINE BOGUSLIB_H 

extern int callme(double* data);  

#ENDIF 

:이 기능이 C 스타일의 헤더 파일을 통해 CGO 컴파일러에 대해 사용할 수 있습니다

extern crate libc; 

#[no_mangle] 
pub extern "C" fn callme(data: &mut [libc::c_double]) -> i32 { 
    data.len() as i32 
} 

//#cgo CFLAGS: -Ipath/to/libfolder 
//#cgo LDFLAGS: -Lpath/to/libfolder -lboguslib 
//#include <boguslib.h> 
import "C" 
import (
    "unsafe" 
    . "fmt" 
) 

func CallmeExternal() { 
    data := make([]float64, 1, 1) 
    data[0] = 1.0 
    ptr := (*C.double)(unsafe.Pointer(&data[0])) 
    size := C.callme(ptr) 

    printf("size %v",size) 
} 

Go 코드는 안전하지 않은 포인터 tri를 사용합니다. 슬라이스가 정의되어 있기 때문에 I 위의 코드를 실행할 때

type Slice struct { 
    data *byte 
    uint32 len 
    uint32 cap 
} 

다음과 같이 CK가 백킹 어레이에 액세스하기 위해 전달 된 기준 길이 엄청나게 커진다. 실제 데이터에 액세스하려면 어떻게해야합니까? 현재 반환되는 것은 무엇입니까?

+5

FFI 인터페이스에서 대상 언어가 이해하는 형식을 고수하고 싶습니다. 여기에서,'& mut [...]'는 그렇지 않습니다. [FFI Omnibus] (http://jakegoulding.com/rust-ffi-omnibus/)를 확인하셨습니까? –

+0

좋아요! 링크 주셔서 감사합니다. – mkultra

답변

5

The Rust FFI Omnibus에 따르면 provided by @matthieu-m으로 코드를 성공적으로 다시 작성했습니다. 함수 시그니처는 대상 언어가 이해하는 형식을 받아 들여야합니다.

// skip include guards 
#include <stdio.h> 

extern int callme(double* slice, size_t len); 

그리고 이동에서 전화가 지금뿐만 아니라

func CallmeExternal() { 
    data := make([]float64, 2, 2) 
    data[0] = 1.0 
    ptr := (*C.double)(unsafe.Pointer(&data[0])) 
    len := C.size_t(len(data)) 
    size := C.callme(ptr, len) 

    printf("size %v",size) 
} 
을 변경 다음과 같이

#[no_mangle] 
pub extern "C" fn callme(slice: *const libc::c_double, len: libc::size_t) -> libc::c_int { 
    let data = slice::from_raw_parts(slice, len as usize); 
    data.len() as i32 
} 

헤더 파일의 선언 :

녹 함수 서명로 변경

이것은 2을 반환합니다.

관련 문제