• 〖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

  • 相关阅读:
    【shell】awk引用外部变量
    【shell】获取第10+个位置参数
    【ELK】Elasticsearch的备份和恢复
    【linux】crontab的环境变量问题
    【linux】如何给sudo的root设置环境变量
    【zabbix】自动注册,实现自动发现agent并添加监控(agent不需要任何配置)
    【windows】如何让一个程序开机自启动
    【linux】如何查看进程运行在那颗cpu上
    【Windows】修改远程桌面端口号
    分享知识-快乐自己:mongodb 安装部署(linux)
  • 原文地址:https://www.cnblogs.com/scue/p/3513049.html
Copyright © 2020-2023  润新知