この質問は、別の質問とみなされるのに十分な新しい情報で、Julia - C interface with nonfundamental typesのフォローアップです。私はmystruct
の三つの可能なバージョンで、このような二つのタイプがありますCライブラリを使用:Julia-C types with struct hack原因segfault
struct contained {
int x;
int y;
int z;
};
struct mystruct {
int n;
//original:
// contained* arr;
//struct hack version 1:
// contained arr[1];
//struct hack version 2:
contained arr[];
};
元の質問から答えを使用して、私は、元のバージョンで正常に動作し、以下の対応ジュリア・タイプを定義しています
type contained
x::Cint
y::Cint
z::Cint
end
type mystruct
n::Cint
arr::Ptr{contained}
end
私はPtr{mystruct}
を返し、ms
として保存ジュリアからC関数を呼び出す場合、私はm = unsafe_load(ms)
を入れてm.n
とポインタを見ることができます:mystruct
ではなく、構造体のハックを使用していずれかのバージョンのですが、元のケースではunsafe_load(m.arr)
の値しか確認できません。それ以外の場合はunsafe_load(m.arr)
がsegfaultを引き起こします。この方法で定義された可変長配列を含むC構造体を扱うJuliaの正しい方法は何ですか?私はmystruct
の元の定義だけをcontained *arr
と使用しますが、これは期待どおりに動作するためですが、他の場合にも機能するコードが必要です。
segfaultの結果として記述したのは、実際には_not_segfaultの場合です。次のコードは、C構造体が 'contained * arr'で定義されているときに、' contains arr [1] 'または' contained arr [] 'でセグメンテーションされたときに期待される出力を出します: ' ms = ccall(:mkmystruct、 Ptr {mystruct}、...) '; 'm = unsafe_load(ms)'; 'n = m.n'; 'arr = [unsigned_load(m.arr、i)in i for 1:n]'; しかし、 'arr = unsafe_wrap(Array、m.arr、m。n) 'と' arr = unsafe_wrap(配列、ms + sizeof(Cint)、m.n) 'はsegfaultsになります。 –
私は例を追加しました。 –
完全な例をありがとう。ここでは、 'mystruct'はJuliaに関する限り' arr'を持っていません。他の 'ccall'で' 'free''になるまで、' 'arr''のメモリが何かによって上書きされないという保証はありますか? –