0

文字列へのポインターを保持するネイティブ C 構造体があります。

struct mystruct {
  char *name;
}

名前にメモリを割り当てるネイティブ関数:

void fill(struct mystruct *s, int count) {
  for (int i = 0; i < count; i++)
    s[i].name = strdup("something");
}

対応する Java 構造体とネイティブ メソッドは次のとおりです。

class MyStruct extends Structure {
  String name;
}

void fill(MyStruct[] structs, int count)いくつかのインスタンスを埋めるために使用されます。次に、これを次のように使用します。

MyStruct[] structs = new MyStruct[10];
fill(structs, structs.length);

void free(MyStruct[] structs)完了したら、配列全体 (strdup によって割り当てられたすべてのメモリ) をクリーンアップするクリーンアップ ルーチンを呼び出す必要があります。構造体のインスタンスごとのメソッドでクリーンアップを行う方法はありません。

私が直面している問題は、配列を解放した後、Java 文字列が壊れていることです。各 MyStruct インスタンスのコピーを作成して、ネイティブ メモリを解放し、純粋な Java 文字列を使用する MyStruct インスタンスだけを処理するにはどうすればよいですか?

4

2 に答える 2

1

をバッキングするネイティブ メモリを解放したらstruct、Java オブジェクトを参照しないようにするか、独自のメモリ バッキングを持つ新しいオブジェクトを作成する必要があります。

メモリを手動で管理する必要がある場合は、フィールドを a にマップせず、代わりにString使用します。Pointer

class MyStruct extends Structure {
    public Pointer name;
    public String getName() { return name == null ? null : name.getString(0); }
}

一般に、 orを呼び出さない限り、ネイティブ メモリ バッキングが解放された後にJNA を使用しても直接はありません(JNA はネイティブ関数呼び出しの前後にこれらのメソッドを自動的に呼び出すことに注意してください)。ただし、そうする場合は、自分が何をしているのかを確認してください。コードを開発するためのより安全な方法があります。StructureStructure.read()Structure.write()

于 2013-08-21T11:40:02.083 に答える