前段时间在做Android下jni的部分,遇到了一些bug和错误,找了好久,给整理了一下,留着以后查找方便
1.c和c++的 mk文件不一样,记着要区分。
网友给一个比较全的文件有:
c++正确的mk文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := TestSm3
LS_CPP=$(subst $(1)/,,$(wildcard $(1)/*.cpp))
LOCAL_SRC_FILES := $(call LS_CPP,$(LOCAL_PATH))
include $(BUILD_SHARED_LIBRARY)
2.就是类型转换的问题
要把各种数据类型都转化好,这样传入的数据才可以。
包括jstring 怎么转为char*之类的
3.还有就是jni下面调用c++中的类还是不一样的。
要这样来调用。
Jni中调用c++中的类要这样来调:
/*
* 测试SM3的口令算法
*/
JNIEXPORT jint JNICALL Java_com_test_testndksm3_JniClient_generateOTPWithSM3
(JNIEnv * env, jclass arg, jobject T0, jobject TC, jobject C, jstring Q, jbyteArray K, jint codeDigits)
{
//算法
CSm3otp *Sm3otp=new CSm3otp;
Sm3otp->hotpWithKey("E65C4257CB8D9C79747B8E21C82AEBEC","000000005034B136",8);
return atoi(Sm3otp->computePassword());
}
4.这种错误为数据类型不匹配的错误
记着转换数据类型,包括jstring 和jbyte之间的转换
--------------------------------------
当时遇到的几个数据类型的转换,都是无误的,我把代码留下:
///// //jstring to char* char* jstringTostring(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("utf-8"); jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); jsize alen = env->GetArrayLength(barr); jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen > 0) { rtn = (char*)malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } env->ReleaseByteArrayElements(barr, ba, 0); return rtn; } /// //char* to jstring jstring toJstring(JNIEnv* env, const char* pat) { jclass strClass = env->FindClass("java/lang/String"); jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V"); jbyteArray bytes = env->NewByteArray(strlen(pat)); env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat); jstring encoding = env->NewStringUTF("utf-8"); return (jstring)env->NewObject(strClass, ctorID, bytes, encoding); } /////