C と Java コードをリンクするには、基本的に 2 つの方法があります。JNA と JNI。
JNAは通常、単純なインターフェースに使用されます。JVM から C ライブラリへの呼び出しのための適切なシグネチャを使用して、共有ライブラリをバインドします。JNA だけでは実行できないこともあります。特に、Java メソッドの呼び出しと C 側での Java オブジェクトの直接変更では、変更を上下に渡すためにすぐに別のレイヤーに行き着いてしまいます。ポイントは、型マップがプリミティブと一部の配列 (バッファー/文字列) 型に制限されていることです: http://jna.java.net/javadoc/overview-summary.html#marshalling。このレイヤーはおそらく簡潔でないコードで構成され、追加のオーバーヘッドが発生します。それでも、C 関数から Java メソッドへの呼び出しは、JNA だけでは不可能です。
Java メソッドを呼び出したり、C で「下から」JVM のオブジェクト内をいじったりする必要がある場合は、JNI から始めます。
あなたの質問から、おそらく Java <> C 機能全体を JVM からではなく C (ネイティブ) 側から実行したいと思うでしょう。この場合、JNI を使用して C/C++ アプリケーションに JVM を埋め込む必要があります: https://stackoverflow.com/a/7506378/1175253
JNI 実装用の C ヘッダーを生成する方法: Eclipse で JNI ヘッダー ファイルを生成する方法
もちろん、C++ を使用して JNI C 関数を実装することもできます (または実装する必要があります)。これにより、RAII などを使用してリソース管理が簡素化されます。
編集
JNI を使ったプログラミング == 火遊び。C 側でのグローバル参照、スレッド、配列のピニングなどに注意してください。実際に JNI を使用する必要があるかどうかは、正確に何を達成したいかによって大きく異なります。
JNIEnv
Java クラスとそのメソッドおよびフィールドを、それぞれ呼び出しまたは変更のために取得できます(Java のリフレクションと同様)。この方法でネイティブ Java (JNI) メソッドを呼び出すことは危険な場合があります。C 実装内で非再帰的ミューテックスをロックすると仮定すると、ネストされた呼び出しがデッドロックに陥る可能性があります。したがって、適切な設計のためだけであっても、通常は C からプレーンな (単純な) Java メソッドを呼び出します。これらのメソッドはネイティブでもなく、独自のネイティブ メソッド自体も呼び出しません。最近のプロジェクトで私が経験したことから、JNI によって生じるオーバーヘッドはごくわずかです。