私はRustにC関数をラップしようとしています。以下の構造体を返しstruct elem* get_list()
C機能:錆でRustから読み取ったときにC構造体が整列していない迷惑データを返すのはなぜですか?
struct elem {
char data[5],
struct elem* next
};
は、私は、関数に次のように宣言しました。 C関数の宣言は、古いバージョンのRustドキュメントに記述されているように*const c_void
を返します。これは書面の時点では見つかりませんでした。
extern "C" {
pub fn get_list() -> *const c_void;
}
構造体がnext
は、リストの次の要素へのポインタであることと、リンクリストを表します。私は*const elem
を返すとポインタと協力して、同じ結果を達成することを試みました。錆の内部では、私は次のように構造体を宣言した:
#[repr(C)]
pub struct elem {
pub data: [u8; 5],
pub next: *const c_void,
}
関数は(タイプelem
の)リンクリストの最初の要素を*const c_void
ポインタを返します。これは、ジャンクデータを読み込む
let head = get_list();
while !head.is_null() {
let el: &elem = mem::transmute(head);
let str = el.data;
let str = CStr::from_bytes_with_nul(&str).unwrap();
//do something
head = el.next();
}
- ポインタが適切に整列されていない、両方の文字列が悪く、非nullで終わる、と:私は次のコードとリンクリストの要素を読み込むしようとしています次のポインタはランダムなデータにつながります(関数がCから直接呼び出されると、リストのサイズが異なります)。
私は機能がelem
へのポインタを返すと、ポインタのみで作業をしてみました、私はel
のアドレスからstr
を核変換してみました - それは、常に同じジャンクデータを読み込みます。正しく整列させるにはどうすればいいですか?
私は配列の代わりにポインタを使ってそれを行う方法を知っています。これはRustのドキュメントで説明されていますが、Cコードを変更することはできません。
には注意してくださいどのようにget_list' 'のCの実装が宣言されていますか? (私は '* const elem'の代わりに' * const c_void'を返す理由について興味があります) – pnkfelix
[これは動作しています](https://play.rust-lang.org/?gist=5f56804e93f608e811727af85d376f52&version=stable ) – red75prime
また、反復のどの時点で、ミスアライメントされたデータが読み込まれているのを見ていますか?最初の 'head = get_list()'の位置がずれていますか?それとも、最初の反復の後のいつかですか? – pnkfelix