zoukankan      html  css  js  c++  java
  • 建立JNI层的本地对象,并与JAVA层交互方法

      最近在做OpenCV4Android开发的时候,需要从摄像头捕获多个图片,传值给本地对象,每次捕获到图片都更新数据,最后将计算得到的数据传给JAVA层,并在界面中显示。经过摸索和调试后,找到了通过本地对象的地址,来实现JAVA和本地类交互的方法。

      下面,通过一个小例子进行示例说明,本例子完成通过点击按钮控件,实现本地对象的成员数据自加,并显示的功能:

    首先这是我们C++类的代码,能实现自加很简单的类,能完成测试就好:

    class TestNDK{
    private:
        int num;
    public:
        TestNDK():num(0){
        }
        void numAddSelf(){
            num++;
        }
        int getNum(){
            return num;
        }
    };

    然后再写一个JAVA类,通过这个类,加载动态链接库和本地函数,还有与本地方法交互的方法,更利于管理:

    package com.pplxlee.testndk;
    
    public class TestNDKClass {
            // 加载动态链接库
        static {
            System.loadLibrary("TestNDK");
        }
        
            // 本地对象的地址,以long的形式保存
        private long mAddr;
        
            // 构造函数调用本地类的创建函数
        TestNDKClass(){
            mAddr = nativeCreateObj();
        }
        
        public void release(){
            nativeRelease(mAddr);
        }
        
        public int getNum(){
            return nativeGetNum(mAddr);
        }
        
        public void numAddSelf(){
            nativeNumAddSelf(mAddr);
        }
        
        
        private static native long nativeCreateObj();
        
        private static native void nativeRelease(long objAddr);
        
        private static native int nativeGetNum(long objAddr);
        
        private static native void nativeNumAddSelf(long objAddr);    
        
    }
            

    下面是实现jni本地方法的代码:

    #include <jni.h>
    
    extern "C"{
    
    // 构造本地对象,一定要用new关键字构造,否则,方法结束后,对象会被垃圾回收,之后通过地址访问,只会得到随机的“垃圾”
    JNIEXPORT jlong JNICALL Java_com_pplxlee_testndk_TestNDKClass_nativeCreateObj(
            JNIEnv *, jclass){
        TestNDK* ndkObjectAddr = new TestNDK();
        return ((long)ndkObjectAddr);
    }
    
    // 有new就必须有delete,最后不要忘记在本地对象不再需要时,释放其内存
    JNIEXPORT void JNICALL Java_com_pplxlee_testndk_TestNDKClass_nativeRelease(
            JNIEnv *, jclass, long addrNdkObject){
        TestNDK* ndkObjectAddr = (TestNDK*)addrNdkObject;
        delete ndkObjectAddr;
    }
    
    JNIEXPORT jint JNICALL Java_com_pplxlee_testndk_TestNDKClass_nativeGetNum(
            JNIEnv *, jclass, long addrNdkObject){
        TestNDK* ndkObjectAddr = (TestNDK*)addrNdkObject;
        return (ndkObjectAddr->getNum());
    }
    
    JNIEXPORT void JNICALL Java_com_pplxlee_testndk_TestNDKClass_nativeNumAddSelf(
            JNIEnv *, jclass, long addrNdkObject){
        TestNDK& ndkObject = *(TestNDK*)addrNdkObject;
        ndkObject.numAddSelf();
    }
    
    }

    下面就是我们的MainActivity

    public class MainActivity extends Activity {
        
        TestNDKClass mObj;
        
        TextView tv;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            mObj = new TestNDKClass();
            
            tv = (TextView)findViewById(R.id.textView1);
            tv.setText(String.valueOf(mObj.getNum()));
            
            Button btn = (Button)findViewById(R.id.button1);
            btn.setOnClickListener(new OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    mObj.numAddSelf();
                    tv.setText(String.valueOf(mObj.getNum()));
                }
            });
            
        }
    
        @Override
        protected void onDestroy(){
            super.onDestroy();
            mObj.release();
        }
        
    }

    运行结果如下图所示,每次点击按钮,数字都会+1:

    每次点击按钮,中间的数据都会+1

  • 相关阅读:
    COF框架集成mongodb驱动
    在 RedHat Enterprise、CentOS 或 Fedora Linux 上安装 MongoDB
    利用RATF框架实现web状态的监控
    利用接口测试框架实现web状态的监控
    uwsgi配置
    NODE_ENV&&cross-env的使用
    局部安装的webpack怎么通过npm脚本执行
    react
    .gitignore无法忽略部分文件/文件夹
    MongoDB
  • 原文地址:https://www.cnblogs.com/pplxlee/p/5721054.html
Copyright © 2011-2022 走看看