〖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