2015-11-22 8 views
5

私はRustライブラリにconst char *静的な文字列をCに公開し、既存のインターフェイス(特にlibrsync)と互換性を持たせたいと考えています。 CヘッダファイルはCでRust FFIに定数文字列を公開するにはどうすればよいですか?

extern char const *my_string; 

を持っていることは、ライブラリは単に私が

pub static my_string: *const libc::c_char = unsafe { "hi\0" as *const libc::c_char }; 

のようなものを試してみたが、これは

を文句錆で

char const *my_string = "hi"; 

を持っているでしょうさ

error: casting `&'static str` as `*const i8` is invalid 

私はそうではないようですコンパイル時の定数式ではないため、CStringなどを使用してください。

答えて

5

これは少し奇妙なるので、私と一緒にクマ...理想的

#[repr(C)] 
pub struct StaticCString(*const u8); 
unsafe impl Sync for StaticCString {} 

#[no_mangle] 
pub static CONST_C_STR: StaticCString = 
    StaticCString(b"a constant c string\0" as *const u8); 

、私たちはいくつかのバイトに公共、静的、unmangled、一定のポインタを持つことができ、右?ただし、このエラーが発生したとして、あなたがそれを行うことはできません。

error: the trait `core::marker::Sync` is not implemented for the type `*const u8` [E0277] 
    pub static CONST_C_STR: *const u8 = b"a constant c string\0" as *const u8; 
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

を私はこのような場合でしょうなぜを通じて思考時間の深い金額を費やしていませんでした。不変ポインタがあまりにも多くの問題を引き起こしてはならないようです...

しかし、私たちはと答えます。私たちのタイプはマルチスレッド環境で使用するのが安全です。そのため、ラッパー型が存在します。つまり、私たちが所有する型に対してSyncを実装することができます。単一要素の構造体であるは、常にがラップされた値と同じ実装である必要がありますが、安全な側になるようにrepr(C)とマークします。

これは単純なCプログラムと協力:

#include <stdio.h> 

extern char * CONST_C_STR; 

int main(int argc, char *argv[]) { 
    printf("%s\n", CONST_C_STR); 
} 
+0

ありがとうございました!それは私が探していたものであり、確かに奇妙です。私はなぜグローバルが '同期'ではないのかという質問に対してhttp://stackoverflow.com/q/33884184/243712を開いた。 – poolie

1

をクレートc_str_macroリテラルさび列に0バイトを追加し、CStr基準としてそれを提示する便利なマクロc_str!を、提供します。

免責事項:私は木枠の著者です。

関連する問題