java call so :only use one struct as input and output parameter
发布日期:2021-06-30 22:16:55 浏览次数:2 分类:技术文章

本文共 6594 字,大约阅读时间需要 21 分钟。

前言

前2天,给同事封装了jni的dll, 因为入参和出参不确定数量,要反复改jni dll的接口定义.

做了实验,只使用一个结构,来传入传出多参数。
整理了一下,给以后的实验留了一个demo. 可以用于windows, linux下java call jni so.

实验工程

工程预览

用一个结构同时承载传入和传出参数的好处 : 只要定了接口名称后,接口就不用再改了。剩下都是实现逻辑的事情。

java测试代码

// @file class_fun_ret_result.java// @brief as in/out param to the so interfacepackage com.my_jni_test;public class class_fun_ret_result {    String str_1;    String str_2;    String str_3;    String str_4;    String str_5;    String str_6;    String str_7;    String str_8;    String str_9;    String str_10;}
// @file class_my_jni_test.java// @brief test libmy_jni_test.so interface(in out multi param on one context struct)// on linux, javac can't support chinese text// so, if want add comment, please use english text// view this class signature// javap -s libmy_jni_test.sopackage com.my_jni_test;import com.my_jni_test.class_fun_ret_result;public class class_my_jni_test{    // native method on our .so    // method must was static    // interface for so project    static public native String do_task(class_fun_ret_result info_out);    static    {             // on linux, load .so        // on win, load .dll        System.load("/usr/lib/libtest_my_jni.so"); // must .so load by full path name        // System.loadLibrary("libmy_jni_test");    }    public  static void main(String[] args)    {        int i = 0;        String str_tmp = "";        System.out.println("* hello my_jni_test.java");        class_fun_ret_result info_rc = new class_fun_ret_result();        info_rc.str_1 = "123456"; // is pin code give by user        str_tmp = do_task(info_rc);        System.out.println("do_task(info_rc) = " + str_tmp);        // info_out.str_2 = pin code retry counter        // info_out.str_2 = ukey sn        System.out.println("pin code retry counter = " + info_rc.str_2);        System.out.println("ukey sn = " + info_rc.str_3);    }}

dll 或 so的代码读写上下文结构的实现

// x.cpp : 定义 DLL 应用程序的导出函数。//#include 
#include
#include
#include
#include
#include "libmy_test_jni.h"#include "./com_my_jni_test_class_my_jni_test.h"#ifndef UINT32#define UINT32 unsigned int#endif #define RC_STRING_DEVICE_WAS_OPEN_OK "ok"#define RC_STRING_DEVICE_WAS_OPEN_ERR "err"jstring pChar2JString(JNIEnv* env, const char* pat);char* JString2pChar(JNIEnv* env, jstring jstr);/* * Class: com_my_jni_test_class_my_jni_test * Method: do_task * Signature: (Lcom/my_jni_test/class_fun_ret_result;)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_my_1jni_1test_class_1my_1jni_1test_do_1task (JNIEnv * p_env, jclass p_class, jobject p_object){ char sz_buf[4096] = {
'\0'}; char sz_ukey_serial_number[0x100] = {
'\0'}; UINT32 ui_pin_code_retry_cnt = 0; jclass p_jclass_object = NULL; jfieldID p_jfieldID_str_1 = NULL; jfieldID p_jfieldID_str_2 = NULL; jfieldID p_jfieldID_str_3 = NULL; std::string str_pin_code_in = ""; jstring jstr = NULL; do { p_jclass_object = p_env->FindClass("com/my_jni_test/class_fun_ret_result"); if (NULL == p_jclass_object) { strcpy(sz_buf, "p_env->FindClass(\"com/my_jni_test/class_fun_ret_result\")"); break; } // get class_fun_ret_result.str_1 p_jfieldID_str_1 = p_env->GetFieldID(p_jclass_object,"str_1","Ljava/lang/String;"); if (NULL == p_jfieldID_str_1) { strcpy(sz_buf, "error : env->GetFieldID(p_jclass_object,\"str_1\",\"Ljava/lang/String;\")"); break; } // get class_fun_ret_result.str_2 p_jfieldID_str_2 = p_env->GetFieldID(p_jclass_object,"str_2","Ljava/lang/String;"); if (NULL == p_jfieldID_str_2) { strcpy(sz_buf, "error : env->GetFieldID(p_jclass_object,\"str_2\",\"Ljava/lang/String;\")"); break; } // get class_fun_ret_result.str_3 p_jfieldID_str_3 = p_env->GetFieldID(p_jclass_object,"str_3","Ljava/lang/String;"); if (NULL == p_jfieldID_str_3) { strcpy(sz_buf, "error : env->GetFieldID(p_jclass_object,\"str_3\",\"Ljava/lang/String;\")"); break; } // get param from context struct jstr = (jstring)p_env->GetObjectField(p_object, p_jfieldID_str_1); str_pin_code_in = JString2pChar(p_env, jstr); memset(sz_buf, 0, sizeof(sz_buf)); if (!do_task((char*)str_pin_code_in.c_str(), &ui_pin_code_retry_cnt, sz_ukey_serial_number, (int)sizeof(sz_ukey_serial_number))) { sprintf(sz_buf, "%s", RC_STRING_DEVICE_WAS_OPEN_ERR); break; } // set content to context struct memset(sz_buf, 0, sizeof(sz_buf)); sprintf(sz_buf, "%d", ui_pin_code_retry_cnt); p_env->SetObjectField(p_object,p_jfieldID_str_2,p_env->NewStringUTF(sz_buf)); memset(sz_buf, 0, sizeof(sz_buf)); sprintf(sz_buf, "%s", sz_ukey_serial_number); p_env->SetObjectField(p_object,p_jfieldID_str_3,p_env->NewStringUTF(sz_buf)); // return string sprintf(sz_buf, "%s", RC_STRING_DEVICE_WAS_OPEN_OK); } while (0); return pChar2JString(p_env, sz_buf);}SO_API bool do_task( char* psz_pin_code, /*OUT*/ unsigned int * pui_pin_code_retry_cnt, /*OUT*/ char* psz_ukey_serial_number, /*IN*/ int i_len_ukey_serial_number){ bool b_rc = false; do { if ((NULL == psz_pin_code) || (NULL == pui_pin_code_retry_cnt) || (NULL == psz_ukey_serial_number) || (i_len_ukey_serial_number < 6)) { break; } strcpy(psz_ukey_serial_number, "A0123456789"); *pui_pin_code_retry_cnt = 6; b_rc = true; } while (0); return b_rc;}jstring pChar2JString(JNIEnv* env, const char* pat){ jclass strClass = env->FindClass("Ljava/lang/String;"); jmethodID ctorID = env->GetMethodID(strClass, "
", "([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);} char* JString2pChar(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;}

转载地址:https://lostspeed.blog.csdn.net/article/details/79175690 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:alg4_gcd
下一篇:tools: generate cross-compiled macros for header file

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月27日 21时34分45秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章