Dev: add expiremental API with automatic #functionName resolving
This commit is contained in:
parent
cf0a3934b9
commit
fa93e4ed20
|
@ -9,94 +9,140 @@ import Foundation
|
|||
import java_swift
|
||||
|
||||
public protocol JNIArgumentProtocol {
|
||||
func value() -> jvalue
|
||||
func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue
|
||||
func sig() -> String
|
||||
}
|
||||
|
||||
public struct jnull: JNIArgumentProtocol {
|
||||
|
||||
public func value() -> jvalue {
|
||||
let className: String
|
||||
|
||||
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||
return jvalue()
|
||||
}
|
||||
|
||||
public func sig() -> String {
|
||||
return "L\(className);"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension jint: JNIArgumentProtocol {
|
||||
|
||||
public func value() -> jvalue {
|
||||
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||
return jvalue(i: self)
|
||||
}
|
||||
|
||||
public func sig() -> String {
|
||||
return "I"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension jbyte: JNIArgumentProtocol {
|
||||
|
||||
public func value() -> jvalue {
|
||||
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||
return jvalue(b: self)
|
||||
}
|
||||
|
||||
public func sig() -> String {
|
||||
return "B"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension jchar: JNIArgumentProtocol {
|
||||
|
||||
public func value() -> jvalue {
|
||||
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||
return jvalue(c: self)
|
||||
}
|
||||
|
||||
public func sig() -> String {
|
||||
return "C"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension jshort: JNIArgumentProtocol {
|
||||
|
||||
public func value() -> jvalue {
|
||||
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||
return jvalue(s: self)
|
||||
}
|
||||
|
||||
public func sig() -> String {
|
||||
return "S"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension jlong: JNIArgumentProtocol {
|
||||
|
||||
public func value() -> jvalue {
|
||||
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||
return jvalue(j: self)
|
||||
}
|
||||
|
||||
public func sig() -> String {
|
||||
return "J"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension jboolean: JNIArgumentProtocol {
|
||||
|
||||
public func value() -> jvalue {
|
||||
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||
return jvalue(z: self)
|
||||
}
|
||||
|
||||
public func sig() -> String {
|
||||
return "Z"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension jfloat: JNIArgumentProtocol {
|
||||
|
||||
public func value() -> jvalue {
|
||||
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||
return jvalue(f: self)
|
||||
}
|
||||
|
||||
public func sig() -> String {
|
||||
return "F"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension jdouble: JNIArgumentProtocol {
|
||||
|
||||
public func value() -> jvalue {
|
||||
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||
return jvalue(d: self)
|
||||
}
|
||||
|
||||
public func sig() -> String {
|
||||
return "D"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension String: JNIArgumentProtocol {
|
||||
|
||||
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||
return jvalue(l: self.localJavaObject(locals))
|
||||
}
|
||||
|
||||
public func sig() -> String {
|
||||
return "Ljava/lang/String;"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension jobject: JNIArgumentProtocol {
|
||||
|
||||
public func value() -> jvalue {
|
||||
public func value(locals: UnsafeMutablePointer<[jobject]>) -> jvalue {
|
||||
return jvalue(l: self)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// For backward compatibility
|
||||
extension jvalue: JNIArgumentProtocol {
|
||||
|
||||
public func value() -> jvalue {
|
||||
return self
|
||||
public func sig() -> String {
|
||||
return "L\(JNIObject.getJavaClassname(javaObject: self));"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -88,10 +88,6 @@ fileprivate let javaFieldLock = NSLock()
|
|||
|
||||
public extension JNICore {
|
||||
|
||||
public var NULL: JNIArgumentProtocol {
|
||||
return jnull()
|
||||
}
|
||||
|
||||
public var TRUE: jboolean {
|
||||
return jboolean(JNI_TRUE)
|
||||
}
|
||||
|
@ -327,8 +323,12 @@ public extension JNICore {
|
|||
|
||||
private func checkArgumentAndWrap<Result>(args: [JNIArgumentProtocol], _ block: (_ argsPtr: UnsafePointer<jvalue>?) -> Result) -> Result {
|
||||
if args.count > 0 {
|
||||
var argsValues = args.map({ $0.value() })
|
||||
var locals = [jobject]()
|
||||
var argsValues = args.map({ $0.value(locals: &locals) })
|
||||
return withUnsafePointer(to: &argsValues[0]) { argsPtr in
|
||||
defer {
|
||||
_ = JNI.check(Void.self, &locals)
|
||||
}
|
||||
return block(argsPtr)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,35 +8,73 @@
|
|||
import Foundation
|
||||
import java_swift
|
||||
|
||||
public class JNIObjectWithClass: JNIObject {
|
||||
|
||||
var privateClassName: String!
|
||||
|
||||
public required init(javaObject: jobject?) {
|
||||
super.init(javaObject: javaObject)
|
||||
privateClassName = JNIObject.getJavaClassname(javaObject: self.javaObject)
|
||||
}
|
||||
|
||||
public required init(javaObject: jobject?, className: String) {
|
||||
super.init(javaObject: javaObject)
|
||||
self.privateClassName = className
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public extension JNIObject {
|
||||
|
||||
public static func getJavaClassname(javaObject: jobject?) -> String {
|
||||
let cls = JNI.api.GetObjectClass(JNI.env, javaObject)
|
||||
let javaClassName = JNI.api.CallObjectMethodA(JNI.env, cls, ClassGetNameMethod, nil)
|
||||
return String(javaObject: javaClassName).replacingOccurrences(of: ".", with: "/")
|
||||
}
|
||||
|
||||
public var className: String {
|
||||
if let jniObject = self as? JNIObjectWithClass {
|
||||
return jniObject.privateClassName
|
||||
}
|
||||
return JNIObject.getJavaClassname(javaObject: self.javaObject)
|
||||
}
|
||||
|
||||
|
||||
|
||||
public func callVoidMethod(_ methodID: jmethodID, _ args: JNIArgumentProtocol..., locals: UnsafeMutablePointer<[jobject]>? = nil) {
|
||||
public func callVoidMethod(_ methodID: jmethodID, _ args: JNIArgumentProtocol...) {
|
||||
checkArgumentAndWrap(args: args, { argsPtr in
|
||||
|
||||
JNI.api.CallVoidMethodA(JNI.env, javaObject, methodID, argsPtr)
|
||||
})
|
||||
}
|
||||
|
||||
private func checkArgumentAndWrap<Result>(args: [JNIArgumentProtocol], _ block: (_ argsPtr: UnsafePointer<jvalue>?) -> Result, locals: UnsafeMutablePointer<[jobject]>? = nil) -> Result {
|
||||
public func callStringMethod(method: String? = nil, functionName: String = #function, _ args: JNIArgumentProtocol...) -> String {
|
||||
let methodName = method ?? String(functionName.split(separator: "(")[0])
|
||||
return String(javaObject: self.internalcallObjectMethod(method: methodName, returnType: "Ljava/lang/String;", args))
|
||||
}
|
||||
|
||||
public func callObjectMethod(method: String? = nil, functionName: String = #function, returnType: String, _ args: JNIArgumentProtocol...) -> jobject? {
|
||||
let methodName = method ?? String(functionName.split(separator: "(")[0])
|
||||
return self.internalcallObjectMethod(method: methodName, returnType: returnType, args)
|
||||
}
|
||||
|
||||
private func internalcallObjectMethod(method: String, returnType: String, _ args: [JNIArgumentProtocol]) -> jobject? {
|
||||
let sig = "(\(args.map({ $0.sig() }).joined()))\(returnType)"
|
||||
let methodID = try! JNI.getJavaMethod(forClass: self.className, method: method, sig: sig)
|
||||
return checkArgumentAndWrap(args: args, { argsPtr in
|
||||
return JNI.api.CallObjectMethodA(JNI.env, javaObject, methodID, argsPtr)
|
||||
})
|
||||
}
|
||||
|
||||
private func checkArgumentAndWrap<Result>(args: [JNIArgumentProtocol], _ block: (_ argsPtr: UnsafePointer<jvalue>?) -> Result) -> Result {
|
||||
if args.count > 0 {
|
||||
var argsValues = args.map({ $0.value() })
|
||||
var locals = [jobject]()
|
||||
var argsValues = args.map({ $0.value(locals: &locals) })
|
||||
return withUnsafePointer(to: &argsValues[0]) { argsPtr in
|
||||
defer {
|
||||
if let locals = locals {
|
||||
_ = JNI.check(Void.self, locals)
|
||||
}
|
||||
_ = JNI.check(Void.self, &locals)
|
||||
}
|
||||
return block(argsPtr)
|
||||
}
|
||||
}
|
||||
else {
|
||||
defer {
|
||||
if let locals = locals {
|
||||
_ = JNI.check(Void.self, locals)
|
||||
}
|
||||
}
|
||||
return block(nil)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue