我试图在Xamrin Android上使用第三方.jar(带有嵌入式资源本机库/ JNI)。目前看起来像Xamarin.Android只支持少于16个参数的方法,我的.jar上的一些方法有更多参数,当我使用绑定项目时,它在编译时生成以下警告,并且不在C#类上生成方法:
Warning 17 More than 16 parameters were found, which goes beyond the maximum number of parameters, in managed type BR.Com.Gertec.Pinpad.PPC C:\Sources\Pay Insight Platform\Development\PI - SDK\PI.SDK.Mobile.Gertec.Drivers.Droid\BINDINGSGENERATOR PI.SDK.Mobile.Gertec.Drivers.Droid
所以,在尝试Xamarin支持后,没有成功,我已经四处寻找并且建议尝试使用 JNIEnv 类来为类创建一个扩展方法绑定项目所以我带来了这个:
public static class PPCBindingExtensions
{
static IntPtr id_ppc_GetEMVCard;
public static void PPC_GetEMVCard(this PPC ppc,
byte bTimeout,
byte bNetwork,
byte bAppType,
Java.Lang.String sIniAmount,
Java.Lang.String sDate,
Java.Lang.String sHour,
Java.Lang.String sTimeStamp,
Java.Util.Concurrent.Atomic.AtomicInteger aiCardType,
Java.Util.Concurrent.Atomic.AtomicInteger aiChipLastStatus,
Java.Util.Concurrent.Atomic.AtomicInteger aiAppTypeSelected,
Java.Util.Concurrent.Atomic.AtomicInteger aiNetworkSelected,
Java.Util.Concurrent.Atomic.AtomicInteger aiAIDIdx,
StringBuffer sTrk1,
StringBuffer sTrk2,
StringBuffer sTrk3,
StringBuffer sPAN,
Java.Util.Concurrent.Atomic.AtomicInteger aiPANSeq,
StringBuffer sAppLabel,
Java.Util.Concurrent.Atomic.AtomicInteger aiServCode,
StringBuffer sCardHolder,
StringBuffer sApplExpir,
Java.Util.Concurrent.Atomic.AtomicInteger bCardExtNum,
StringBuffer sBalance,
Java.Util.Concurrent.Atomic.AtomicLong alIssuerCode,
StringBuffer sAcquirerData)
{
var a = JNIEnv.FindClass("br/com/gertec/pinpad/PPC");
if (id_ppc_GetEMVCard == IntPtr.Zero)
{
id_ppc_GetEMVCard = JNIEnv.GetMethodID(ppc.Handle, "PPC", "(BBBLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/lang/StringBuffer;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/lang/StringBuffer;Ljava/util/concurrent/atomic/AtomicLong;Ljava/lang/StringBuffer;)V");
}
JNIEnv.CallVoidMethod(ppc.Handle, id_ppc_GetEMVCard, new JValue(bNetwork),
new JValue(bAppType), new JValue(sIniAmount), new JValue(sDate), new JValue(sHour),
new JValue(sTimeStamp), new JValue(aiCardType), new JValue(aiChipLastStatus),
new JValue(aiAppTypeSelected), new JValue(aiNetworkSelected), new JValue(aiAIDIdx),
new JValue(sTrk1), new JValue(sTrk2), new JValue(sTrk3), new JValue(sPAN),
new JValue(aiPANSeq), new JValue(sAppLabel), new JValue(aiServCode),
new JValue(sCardHolder), new JValue(sApplExpir), new JValue(bCardExtNum),
new JValue(sBalance), new JValue(alIssuerCode), new JValue(sAcquirerData));
}
}
所以,现在当我使用我的绑定生成类时,我确实有丢失的方法,它接收的参数完全相同。
我已使用 javap 实用程序获取JNI的方法签名,该签名随附于 JNIEnv.GetMethodID :
public void PPC_GetEMVCard(byte, byte, byte, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.lang.StringBuffer, java.lang.StringBuffer, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicLong, java.lang.StringBuffer) throws java.lang.NullPointerException, br.com.gertec.pinpad.PPCBusyException, br.com.gertec.pinpad.PPCCommunicationException, br.com.gertec.pinpad.PPCEMVException, br.com.gertec.pinpad.PPCGSerPortException, br.com.gertec.pinpad.PPCHandleException, br.com.gertec.pinpad.PPCIdentificationException, br.com.gertec.pinpad.PPCJNIException, br.com.gertec.pinpad.PPCProtocolCommandException, br.com.gertec.pinpad.PPCProtocolMessagesException, br.com.gertec.pinpad.PPCSerialPortException, br.com.gertec.pinpad.PPCGeneralException;
Signature: (BBBLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/lang/StringBuffer;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/lang/StringBuffer;Ljava/util/concurrent/atomic/AtomicLong;Ljava/lang/StringBuffer;)V
到目前为止一直这么好......我实例化了绑定生成的类,调用它生成的所有方法就好了...唯一的问题是当我调用方法时我会这样做创建它只是使应用程序崩溃并在输出窗口上显示此(非常长)转储:
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: jclass has wrong type: br.com.gertec.pinpad.PPC
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] in call to GetMethodID
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] from void mono.android.view.View_OnClickListenerImplementor.n_onClick(android.view.View)
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] "main" prio=5 tid=1 Runnable
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] | group="main" sCount=0 dsCount=0 obj=0x73ada2e0 self=0xb874e530
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] | sysTid=3140 nice=0 cgrp=apps sched=0/0 handle=0xb6fb5ec8
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] | state=R schedstat=( 0 0 0 ) utm=260 stm=41 core=0 HZ=100
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] | stack=0xbe4c8000-0xbe4ca000 stackSize=8MB
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] | held mutexes= "mutator lock"(shared held)
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] native: #00 pc 00004c58 /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23)
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] native: #01 pc 000034c1 /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] native: #02 pc 00252745 /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+84)
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] native: #03 pc 00236223 /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+162)
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] native: #04 pc 000b1285 /system/lib/libart.so (art::JniAbort(char const*, char const*)+620)
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] native: #05 pc 000b19b5 /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+68)
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] native: #06 pc 000b3385 /system/lib/libart.so (art::ScopedCheck::CheckInstance(art::ScopedCheck::InstanceKind, _jobject*)+172)
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] native: #07 pc 000b3dbb /system/lib/libart.so (art::ScopedCheck::Check(bool, char const*, ...) (.constprop.128)+514)
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] native: #08 pc 000b7087 /system/lib/libart.so (art::CheckJNI::GetMethodID(_JNIEnv*, _jclass*, char const*, char const*)+58)
11-28 21:09:38.048 F/art ( 3140): art/runtime/check_jni.cc:65] native: #09 pc 0005fa14 (???)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at mono.android.view.View_OnClickListenerImplementor.n_onClick(Native method)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at mono.android.view.View_OnClickListenerImplementor.onClick(View_OnClickListenerImplementor.java:29)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at android.view.View.performClick(View.java:4756)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at android.view.View$PerformClick.run(View.java:19749)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at android.os.Handler.handleCallback(Handler.java:739)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at android.os.Handler.dispatchMessage(Handler.java:95)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at android.os.Looper.loop(Looper.java:135)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at android.app.ActivityThread.main(ActivityThread.java:5221)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at java.lang.reflect.Method.invoke!(Native method)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at java.lang.reflect.Method.invoke(Method.java:372)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
11-28 21:09:38.049 F/art ( 3140): art/runtime/check_jni.cc:65]
11-28 21:09:38.368 F/art ( 3140): art/runtime/runtime.cc:284] Runtime aborting...
11-28 21:09:38.368 F/art ( 3140): art/runtime/runtime.cc:284] Aborting thread:
11-28 21:09:38.368 F/art ( 3140): art/runtime/runtime.cc:284] "main" prio=5 tid=1 Native
11-28 21:09:38.368 F/art ( 3140): art/runtime/runtime.cc:284] | group="" sCount=0 dsCount=0 obj=0x73ada2e0 self=0xb874e530
11-28 21:09:38.368 F/art ( 3140): art/runtime/runtime.cc:284] | sysTid=3140 nice=0 cgrp=apps sched=0/0 handle=0xb6fb5ec8
11-28 21:09:38.368 F/art ( 3140): art/runtime/runtime.cc:284] | state=R schedstat=( 0 0 0 ) utm=264 stm=42 core=0 HZ=100
11-28 21:09:38.369 F/art ( 3140): art/runtime/runtime.cc:284] | stack=0xbe4c8000-0xbe4ca000 stackSize=8MB
11-28 21:09:38.369 F/art ( 3140): art/runtime/runtime.cc:284] | held mutexes= "abort lock" "mutator lock"(shared held)
我做错了什么?
PS:还有更多的日志会使所有线程的流产变得迟钝...为了简单起见,我刚刚发布了第一个块。谢谢,我非常感谢你的帮助! Gutemberg
- ==更多问题== - 好的,我向前迈进了一步......文档中没有提到GetMethodID的第一个参数是CLASS指针/处理程序,而不是intance指针/处理程序。
所以现在我做了:
var classHandler = JNIEnv.FindClass("br/com/gertec/pinpad/PPC");
和
JNIEnv.GetMethodID(classHandler,....
我现在有了方法指针/处理程序。
现在我又发生了一次崩溃,说我将无效参数传递给CallVoidMethod(),即发送到本机方法:
11-28 22:17:18.322 E/art ( 7365): JNI ERROR (app bug): attempt to pass an instance of java.lang.StringBuffer as argument 12 to void br.com.gertec.pinpad.PPC.PPC_GetEMVCard(byte, byte, byte, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.lang.StringBuffer, java.lang.StringBuffer, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicLong, java.lang.StringBuffer)
11-28 22:17:18.322 E/art ( 7365): JNI ERROR (app bug): attempt to pass an instance of java.util.concurrent.atomic.AtomicInteger as argument 16 to void br.com.gertec.pinpad.PPC.PPC_GetEMVCard(byte, byte, byte, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.lang.StringBuffer, java.lang.StringBuffer, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicLong, java.lang.StringBuffer)
(and more others like this)
关键是,正如你在主帖上看到的那样,传递了所有参数,这里是方法的Java签名:
public void PPC_GetEMVCard(byte, byte, byte, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.lang.StringBuffer, java.lang.StringBuffer, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicInteger, java.lang.StringBuffer, java.util.concurrent.atomic.AtomicLong, java.lang.StringBuffer) throws java.lang.NullPointerException, br.com.gertec.pinpad.PPCBusyException, br.com.gertec.pinpad.PPCCommunicationException, br.com.gertec.pinpad.PPCEMVException, br.com.gertec.pinpad.PPCGSerPortException, br.com.gertec.pinpad.PPCHandleException, br.com.gertec.pinpad.PPCIdentificationException, br.com.gertec.pinpad.PPCJNIException, br.com.gertec.pinpad.PPCProtocolCommandException, br.com.gertec.pinpad.PPCProtocolMessagesException, br.com.gertec.pinpad.PPCSerialPortException, br.com.gertec.pinpad.PPCGeneralException;
我无法看到任何差异......