c/c++调用JAVA方法 与 java通过反射调用JAVA方法 原理一样。java通过类、方法名、参数 来唯一确定一个方法。 1.通过包名找到Java中的类名 2.获取java类中方法id:参数一为类对象,参数二为java中方法名,参数三为方法唯一签名 3.执行调用
先看java通过反射调用JAVA方法
public class Jk {
public void p(String s) {
System. out.println(s);
}
}
//另一个Test类来反射此类,执行p(String)方法
public class Test {
public static void main(String[] args) {
try {
Class clazz = Test.class.getClassLoader().loadClass("Jk" );
Method method = clazz.getDeclaredMethod("p" ,new Class[] { String.class });
method.invoke(clazz.newInstance(), new String[] { "java反射" });
} catch (Exception e) {
e.printStackTrace();
}
}
}
加入JDK路径到Path :C:\Program Files\Android\Android Studio\jre\bin
cd C:\Users\FT\AndroidStudioProjects\SoftPos\app\build\intermediates\javac\debug\classes
javap -s com.ft.softpos.SoftPos
获得类下面所有方法的签名
C:\Users\FT\AndroidStudioProjects\SoftPos\app\build\intermediates\javac\debug\classes>javap -s com.ft.softpos.SoftPos
Compiled from "SoftPos.java"
public class com.ft.softpos.SoftPos {
public static java.lang.String className;
descriptor: Ljava/lang/String;
public com.ft.softpos.SoftPos();
descriptor: ()V
public java.lang.Short halWaitCard(java.lang.Short, java.lang.Byte[], java.lang.Byte[], java.lang.Byte[]);
descriptor: (Ljava/lang/Short;[Ljava/lang/Byte;[Ljava/lang/Byte;[Ljava/lang/Byte;)Ljava/lang/Short;
public java.lang.Short halSendApdu(java.lang.Byte, java.lang.Byte[], java.lang.Byte[], java.lang.Short, java.lang.Byte[], java.lang.Byte[], java.lang.Byte[], java.lang.Byte);
descriptor: (Ljava/lang/Byte;[Ljava/lang/Byte;[Ljava/lang/Byte;Ljava/lang/Short;[Ljava/lang/Byte;[Ljava/lang/Byte;[Ljava/lang/Byte;Ljava/lang/Byte;)Ljava/lang/Short;
public java.lang.Short halRFCardClose();
descriptor: ()Ljava/lang/Short;
public native void test();
descriptor: ()V
static {};
descriptor: ()V
}
C:\Users\FT\AndroidStudioProjects\SoftPos\app\build\intermediates\javac\debug\classes>
test()是JAVA调用C语言方法,用于测试,在test()方法里回调JAVA方法。 如果参数不对,as会有提示,按提示也能得到参数签名。
#include <jni.h>
#include <string>
#include <Android/log.h>
#define LOG "SoftPos"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG,__VA_ARGS__)
extern "C"
JNIEXPORT void JNICALL
Java_com_ft_softpos_SoftPos_test(JNIEnv *env, jobject thiz) {
// TODO: implement test()
/* 通过包名找到Java中的类名 */
jclass clazz = env->FindClass("com/ft/softpos/SoftPos");
if (clazz == 0)
{
LOGE("failed to find class SoftPos");
}
else
{
LOGE("find class SoftPos succeed!");
}
/* 获取java类中方法id:参数一为类对象,参数二为java中方法名,参数三为方法唯一签名 */
jmethodID jId = env->GetMethodID(clazz, "halRFCardClose", "()Ljava/lang/Short;");
if (jId == 0)
{
LOGE("failed to find method in java!");
}
else
{
LOGE("find method succeed!");
}
/* 调用java中的方法 */
env->CallObjectMethod(thiz, jId);
}
回调成功。