zoukankan      html  css  js  c++  java
  • 〖Linux〗Android NDK调用已编译好的C/C++动态连接库(so文件)

    一、背景:假定已有应用程序zigbeeclient.cpp,内容如下:

    ...
    extern "C" {
        int getresult(int argc, char **argv);
    }
    
    int getresult(int argc, char **argv)
    { 
        ...
    }

      这个文件生成一个动态链接库libzigbee.so

    $(CXX) $(CXXFLAGS) $(MYCLIENTCFLAGS) $(LDFALGS) $(INCLUDE) -fPIC -llog -shared $^ -o libzigbee.so

    二、期望:能在Android任意一个的NDK应用程序中,可调用此库中的getresult()函数

      1. 编写NDK的C语言文件zigbeeclient.c,内容如下:

    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <jni.h>
    
    /*-----------------------------------------------------------------------------
     *  从libzigbee.so中调用进来的函数
     *-----------------------------------------------------------------------------*/
    int getresult(int argc, char **argv);
    
    /*-----------------------------------------------------------------------------
     *  String to char*
     *-----------------------------------------------------------------------------*/
    char* jstring_to_pchar(JNIEnv* env, jstring str)
    {
        char* pstr = NULL;
        jclass clsstring = (*env)->FindClass(env, "java/lang/String");
        jstring strencode = (*env)->NewStringUTF(env, "utf-8");
        jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes",
                    "(Ljava/lang/String;)[B");
        jbyteArray byteArray = (jbyteArray)(
                    (*env)->CallObjectMethod(env, str, mid, strencode));
        jsize size = (*env)->GetArrayLength(env, byteArray);
        jbyte* pbyte = (*env)->GetByteArrayElements(env, byteArray, JNI_FALSE);
        if (size > 0)
        {
            pstr = (char*) malloc(size);
            memcpy(pstr, pbyte, size);
        }
        return pstr;
    }
    
    jstring
    Java_com_scue_zigbeeclient_ZigbeeActivity_getResultJni( JNIEnv* env, jobject thiz ,
            jstring subdev, jstring ctrltype, jstring mod, jstring server)
    {
        int ret=0;
        int argc = 4;
        char *argv[4];
        argv[0]=jstring_to_pchar(env, subdev);
        argv[1]=jstring_to_pchar(env, ctrltype);
        argv[2]=jstring_to_pchar(env, mod);
        argv[3]=jstring_to_pchar(env, server);
        ret = getresult(argc, argv);
        char cret[10]="";
        sprintf(cret, "%d", ret);
        return (*env)->NewStringUTF(env, cret);
    }

      2. 编写Android.mk文件:

    # Copyright (C) 2009 The Android Open Source Project
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    #
    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE := zigbee-prebult
    LOCAL_SRC_FILES := libs/libzigbee.so
    include $(PREBUILT_SHARED_LIBRARY)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE    := hello-jni
    LOCAL_SRC_FILES := hello-jni.c
    LOCAL_SHARED_LIBRARIES := zigbee-prebult
    include $(BUILD_SHARED_LIBRARY)

      3. 在Java程序文件中,load动态库的顺序有讲究(后一个依赖于前一个):

    public native String  getResultJni(String subdev, String ctrltype, String mod, String server);
    static {
        System.loadLibrary("zigbee");
        System.loadLibrary("zigbeeclient");        
    }

      4. 其他的细节可以下载我打包好的tar文件:Android_NDK_Extra_So.tgz

  • 相关阅读:
    写一个通用的事件侦听器函数
    基于LuckySheet在线表格的Excel下载功能开发
    node项目中npm 第三方包引用规则
    js 本地保存 json/txt 文件
    letcood 算法题 -- 两数相加
    ES6新增语法总结
    关于Promise,你必须知道的几点。
    Promise 基础
    学习网页收藏
    android Listview每一个item添加点击事件
  • 原文地址:https://www.cnblogs.com/scue/p/3513049.html
Copyright © 2011-2022 走看看