日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

JNI包装c++类

發(fā)布時(shí)間:2025/7/25 c/c++ 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JNI包装c++类 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

section 1

  • 定義c++類和方法
    singleton PluginLoader @ namespace Vamp::HostExt
    Plugin @ namespace Vamp
    方案一:map一個(gè)java的class到c++的PluginLoader,返回類型太復(fù)雜,廢棄
  • class PluginLoader {public:static PluginLoader *getInstance();Plugin* loadPlugin(PluginKey key,float inputSampleRate,int adapterFlags=0) {// ... other methods for later} };class PluginBase {public:virtual std::string getIdentifier() const = 0;virtual std::string getName() const = 0;virtual std::string getDescription() const = 0;virtual int getPluginVersion() const = 0;// ... other methods for later };
  • 設(shè)計(jì)java類
    PluginBase是純虛類直接映射為java的Interface,這個(gè)做法留作后面的章節(jié)重構(gòu)
  • package org.vamp_plugins; public class Plugin {public native String getIdentifier();public native String getName();public native String getDescription();public native int getPluginVersion(); }package org.vamp_plugins; public class PluginLoader {public class LoadFailedException extends Exception {};public static synchronized PluginLoader getInstance() {// some magic here}public Plugin loadPlugin(String key, float inputSampleRate)throws LoadFailedException {// and here} }
    • native對象handle
      通過對象的handle,以上的兩個(gè)java類直接對應(yīng)于c++的類
      PluginLoader類更新如下:
    public class PluginLoader {public class LoadFailedException extends Exception {};public static synchronized PluginLoader getInstance() {if (inst = null) {inst = new PluginLoader();inst.initialise();}return inst;}public Plugin loadPlugin(String key, float inputSampleRate)throws LoadFailedException {long handle = loadPluginNative(key, inputSampleRate);if (handle != 0) return new Plugin(handle);else throw new LoadFailedException();}private PluginLoader() { initialise(); }private static PluginLoader inst;private long nativeHandle;private native long loadPluginNative(String key, float inputSampleRate);private native void initialise(); }public class Plugin {private long nativeHandle;protected Plugin(long handle) {nativeHandle = handle; }public native String getIdentifier();public native String getName();public native String getDescription();public native int getPluginVersion(); }
    • 生成jni函數(shù)聲明
      javac和javah就可做這些事
    $ javac org/vamp_plugins/*.java $ javah -jni org.vamp_plugins.Plugin org.vamp_plugins.PluginLoader $ ls -1 org org_vamp_plugins_Plugin.h org_vamp_plugins_PluginLoader.h sample.h $

    生成的頭文件內(nèi)容片段:

    JNIEXPORT jstring JNICALL Java_org_vamp_1plugins_Plugin_getIdentifier(JNIEnv*, jobject);

    JNIEnv*:當(dāng)前jni函數(shù)的運(yùn)行環(huán)境
    jobject:調(diào)用當(dāng)前函數(shù)的this指針

    section 2

  • 實(shí)現(xiàn)jni函數(shù)
    handle.h =>
  • #ifnef __HANDLE_H_INCLUDE__ #define _HANDLE_H_INCLUDE__jfieldID getHandleField(JNIEnv* env, jobject ojb) {jclass c = env->GetObjectClass(obj);// J is the type singure for long:return env->getFieldID(c, "nativeHandle", "J"); }template <typename T> T* getHandle(JNIEnv* env, jobject obj) {jlong handle = env->GetLongField(obj, getHandleField(env, obj));return reinterpret_cast<T*>(handle); }template <typename T> T* setHandle(JNIEnv* env, jobject obj, T* t) {jlong handle = reinterpret_cast<jlong>(t);env->SetLongField(obj, getHandleField(env, obj), handle); }#endif

    pluginloader.cc =>

    #include "org_vamp_plugins_PluginLoader.h" #include <vamp-hostsdk/PluginLoader.h> #include "handle.h"using Vamp::Plugin; using Vamp::HostExt::PluginLoader;void Java_org_vamp_lpugins_PluginLoader_initialise(JNIEnv* env, jobject obj) {PluginLoader* inst = PluginLoader::getInstance();setHandle(env, obj, inst); }jlong Java_org_vamp_lplugins_PluginLoader_loadPluginNative(JNIEnv* env, jobject obj,jstring key, jfloat rate) {PluginLoader* inst = getHandle<PluginLoader>(env, obj);const char* kstr = env->GetStringUTFChars(key, 0);Plugin* p = inst->loadPlugin(kstr, rate);env->ReleaseStringUTFChars(key, kstr);return (jlong)p; }

    plugin.cc =>

    #include "org_vamp_plugins_plugin.h" #include <vamp-hostsdk/plugin.h> #include "handle.h"using Vamp::Plugin; using std::string;jstring Java_org_vamp_1plugins_Plugin_getIdentifier(JNIEnv *env, jobject obj) {Plugin *p = getHandle<Plugin>(env, obj);return env->NewStringUTF(p->getIdentifier().c_str()); }jstring Java_org_vamp_1plugins_Plugin_getName(JNIEnv *env, jobject obj) {Plugin *p = getHandle<Plugin>(env, obj);return env->NewStringUTF(p->getName().c_str()); }jstring Java_org_vamp_1plugins_Plugin_getDescription(JNIEnv *env, jobject obj) {Plugin *p = getHandle<Plugin>(env, obj);return env->NewStringUTF(p->getDescription().c_str()); }jint Java_org_vamp_1plugins_Plugin_getPluginVersion(JNIEnv *env, jobject obj) {Plugin *p = getHandle<Plugin>(env, obj);return p->getPluginVersion(); }
  • 寫一個(gè)測試程序
  • package org.vamp_plugins;public class test {public static void main(String[] args) {// This is the name of a Vamp plugin we know we have installedString key = "vamp-example-plugins:percussiononsets";PluginLoader loader = PluginLoader.getInstance();try {Plugin p = loader.loadPlugin(key, 44100);System.out.println("identifier: " + p.getIdentifier());System.out.println("name: " + p.getName());System.out.println("description: " + p.getDescription());System.out.println("version: " + p.getPluginVersion());} catch (PluginLoader.LoadFailedException e) {System.out.println("Plugin load failed");}} }

    section 3

    • 處理c++對象
      Java有g(shù)c,而c++需要手動(dòng)管理內(nèi)存,有下面兩種方法:
  • 添加一個(gè)方法,讓java層調(diào)用刪除對象
  • 在java的finialize() 中刪除對象
    第二種方法,看似完善,但是java的gc難以精準(zhǔn)控制native對象的狀態(tài),多線程情況下更不確定,
    所以只能使用方法一:添加 dispose方法
  • public native void dispose(); void Java_org_vamp_1plugins_Plugin_dispose(JNIEnv* env, jobject obj) {Plugin* p = getHandle(env, obj);setHandle(env, obj, 0);delete p; }

    section 4

    • 復(fù)雜一點(diǎn)的用法
    typedef std::vector<Feature> FeatureList; typedef std::map<int, FeatureList> FeatureSet; virtual FeatureSet process(const float* const* inputBuffers,RealTime timestamp) = 0;java 沒有typedef 對應(yīng)map如下 public native Map<Integer, ArrayList<Feature>>process(float[][] inputBuffers, RealTime timestamp); - 在jni層構(gòu)建java對象 jclass featClass = env->FindClass("org/vamp_plugins/Feature"); jmethodID ctor = env->GetMethodID(featClass, "<init>", "()V"); jobject feature = env->NewObject(featClass, ctor); - jni處理泛型 jclass treeMapClass = env->FindClass("java/util/TreeMap"); jmethodID treeMapCtor = env->GetMethodID(treeMapClass, "<init>", "()V"); jobject map = env->NewObject(treeMapClass, treeMapCtor); - 從多維數(shù)組中取數(shù)據(jù) jobject Java_org_vamp_1glugins_Plugin_process(JNIEnv* env, jobject obj,jobjectArray inputBuffers, jobject timestamp);int channels = env->GetArrayLength(data); float **input = new float *[channels];for (int c = 0; c < channels; ++c) {jfloatArray cdata =(jfloatArray)env->GetObjectArrayElement(data, c);input[c] = env->GetFloatArrayElements(cdata, 0); }for (int c = 0; c < channels; ++c) {jfloatArray cdata =(jfloatArray)env->GetObjectArrayElement(data, c);env->ReleaseFloatArrayElements(cdata, input[c], 0); }delete[] input;

    That's all, thx for reading, hope it's been useful
    譯自:http://thebreakfastpost.com/2012/03/06/wrapping-a-c-library-with-jni-part-1/

    轉(zhuǎn)載于:https://www.cnblogs.com/octave/p/5073958.html

    總結(jié)

    以上是生活随笔為你收集整理的JNI包装c++类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。