JNI工具
来源:锐游网
1.生成.h文件
import re
import os
def parse_native_methods(java_file_content):
"""解析 Java 源文件中的 native 方法声明"""
native_methods = []
class_name = None
# 正则表达式来匹配类名和 native 方法
class_pattern = re.compile(r'\bclass\s+(\w+)')
method_pattern = re.compile(r'\b(native\s+[\w\s<>]+\s+\w+\s*\(.*?\));')
for line in java_file_content.split('\n'):
class_match = class_pattern.search(line)
if class_match:
class_name = class_match.group(1)
method_match = method_pattern.search(line)
if method_match:
method_declaration = method_match.group(1)
native_methods.append(method_declaration.strip())
return class_name, native_methods
def jni_signature(java_class_name, method):
"""生成 JNI 方法签名"""
# 提取返回类型和方法签名
method_signature = re.match(r'([\w\s<>]+)\s+(\w+)\s*\((.*?)\)', method)
if method_signature:
return_type, method_name, parameters = method_signature.groups()
params = parameters.split(',') if parameters else []
# JNI 类型映射
type_mapping = {
'void': 'void',
'int': 'jint',
'long': 'jlong',
'boolean': 'jboolean',
'byte': 'jbyte',
'char': 'jchar',
'short': 'jshort',
'float': 'jfloat',
'double': 'jdouble',
'String': 'jstring'
}
jni_params = ', '.join(['JNIEnv* env, jobject obj'] + [
f'{type_mapping.get(p.strip().split()[0], "jobject")} {p.strip().split()[-1]}' for p in params if
p.strip()])
# 将 Java 类名转换为 JNI 方法名
jni_class_name = java_class_name.replace('.', '_')
jni_method_name = f'Java_{jni_class_name}_{method_name}'
return f'JNIEXPORT {type_mapping.get(return_type.strip(), "jobject")} JNICALL {jni_method_name}({jni_params});'
return None
def generate_header_file(java_class_name, native_methods, header_file_path):
"""生成 JNI 头文件"""
with open(header_file_path, 'w') as header_file:
header_guard = f'_{java_class_name.upper()}_H_'
header_file.write(f'#ifndef {header_guard}\n')
header_file.write(f'#define {header_guard}\n\n')
header_file.write('#include <jni.h>\n\n')
for method in native_methods:
method_declaration = jni_signature(java_class_name, method)
if method_declaration:
header_file.write(f'{method_declaration}\n')
header_file.write(f'\n#endif // {header_guard}\n')
def main():
java_file_path = input("请输入 Java 源文件路径: ").strip()
header_file_dir = input("请输入头文件输出目录: ").strip()
if not os.path.exists(java_file_path):
print(f"文件 {java_file_path} 不存在")
return
if not os.path.isdir(header_file_dir):
print(f"目录 {header_file_dir} 不存在")
return
with open(java_file_path, 'r') as java_file:
java_file_content = java_file.read()
class_name, native_methods = parse_native_methods(java_file_content)
if not class_name or not native_methods:
print("未能解析到类名或 native 方法")
return
header_file_path = os.path.join(header_file_dir, f'{class_name}.h')
generate_header_file(class_name, native_methods, header_file_path)
print(f"头文件已生成到 {header_file_path}")
if __name__ == '__main__':
main()
2.生成属性签名
def get_jni_type_signature(java_type):
# 基本类型和数组类型的映射
java_to_jni = {
"boolean": "Z",
"byte": "B",
"char": "C",
"short": "S",
"int": "I",
"long": "J",
"float": "F",
"double": "D",
"void": "V",
"boolean[]": "[Z",
"byte[]": "[B",
"char[]": "[C",
"short[]": "[S",
"int[]": "[I",
"long[]": "[J",
"float[]": "[F",
"double[]": "[D",
"String": "Ljava/lang/String;",
"Object": "Ljava/lang/Object;",
"String[]": "[Ljava/lang/String;",
"Object[]": "[Ljava/lang/Object;"
}
if java_type in java_to_jni:
return java_to_jni[java_type]
if java_type.endswith("[]"):
element_type = java_type[:-2]
return f"[{get_jni_type_signature(element_type)}"
else:
return f"L{java_type.replace('.', '/')};"
def get_method_signature(method_signature):
try:
# 提取类名和方法
class_and_method, param_and_return = method_signature.split('#')
class_name = class_and_method.strip()
param_and_return = param_and_return.split(':')
method_and_params = param_and_return[0].split('(')
method_name = method_and_params[0].strip()
param_list = method_and_params[1][:-1].split(',') if len(method_and_params) > 1 else []
return_type = param_and_return[1].strip() if len(param_and_return) > 1 else 'void'
# 生成参数签名
param_signature = ''.join([get_jni_type_signature(param.strip()) for param in param_list])
# 生成方法签名
return f"({param_signature}){get_jni_type_signature(return_type)}"
except Exception as e:
print(f"Error parsing method signature: {e}")
return None
def main():
while True:
java_signature = input(
"请输入Java方法签名(例如:com.hfengxiang.app.HelloJNI#init(android.os.Bundle, String):String,输入exit退出):")
if java_signature.lower() == "exit":
break
jni_signature = get_method_signature(java_signature)
if jni_signature:
print(f"Java方法签名 '{java_signature}' 对应的JNI方法签名是: {jni_signature}")
else:
print(f"无法解析Java方法签名 '{java_signature}'")
if __name__ == "__main__":
main()
因篇幅问题不能全部显示,请点此查看更多更全内容