在Xamarin.Android中加载.so文件

我正在尝试在Xamarin.Android中将Java类转换为C#。

原始的Java类有这个:

private native boolean OpenDeviceCtx(Object obj); public native boolean CloseDevice(); public native boolean GetDiodesStatus(byte[] bArr); public native boolean GetFrame(byte[] bArr); public native boolean GetImage(int i, byte[] bArr); public native boolean GetImage2(int i, byte[] bArr); public native boolean GetImageByVariableDose(int i, byte[] bArr); public native boolean GetImageSize(); public native boolean GetInterfaces(byte[] bArr); public native String GetVersionInfo(); public native boolean IsFingerPresent(); public native boolean OpenDevice(); public native boolean OpenDeviceOnInterface(int i); public native boolean Restore7Bytes(byte[] bArr); public native boolean RestoreSecret7Bytes(byte[] bArr, byte[] bArr2); public native boolean Save7Bytes(byte[] bArr); public native boolean SaveSecret7Bytes(byte[] bArr, byte[] bArr2); public native boolean SetDiodesStatus(int i, int i2); public native boolean SetGlobalSyncDir(String str); public native boolean SetLogOptions(int i, int i2); public native boolean SetNewAuthorizationCode(byte[] bArr); public native boolean SetOptions(int i, int i2); static { System.loadLibrary("usb-1.0"); System.loadLibrary("ftrScanAPI"); System.loadLibrary("ftrScanApiAndroidJni"); } 

我认为这种“原生”方法是.so库中的方法。 我对么?

因此,要在我的Xamarin.Android项目中加载这些库,我尝试这样做:

 [DllImport("usb-1.0")] public static extern int GetUSB(); [DllImport("ftrScanAPI")] public static extern int GetScanAPI(); [DllImport("ftrScanApiAndroidJni")] public static extern int GetScanAPIAndroidJNI(); 

并在我的项目中创建了一个文件夹结构,如: project / lib / arm / files.so

当我运行项目时,我遇到了很多错误:

 DllImport attempting to load: 'usb-1.0'. DllImport error loading library '/storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0" not found'. DllImport error loading library '/storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0.so" not found'. DllImport error loading library '/system/lib/libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//system/lib/libusb-1.0" not found'. DllImport error loading library '/system/lib/libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//system/lib/libusb-1.0.so" not found'. DllImport error loading library 'libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0" not found'. DllImport error loading library 'libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0.so" not found'. DllImport error loading library 'usb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/usb-1.0" not found'. DllImport error loading library '/storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0" not found'. DllImport error loading library '/storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0.so" not found'. DllImport error loading library '/system/lib/libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//system/lib/libusb-1.0" not found'. DllImport error loading library '/system/lib/libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//system/lib/libusb-1.0.so" not found'. DllImport error loading library 'libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0" not found'. DllImport error loading library 'libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0.so" not found'. DllImport error loading library 'libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0" not found'. DllImport unable to load library 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0" not found'. DllImport attempting to load: 'usb-1.0'. DllImport error loading library '/storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0" not found'. DllImport error loading library '/storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0.so" not found'. DllImport error loading library '/system/lib/libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//system/lib/libusb-1.0" not found'. DllImport error loading library '/system/lib/libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//system/lib/libusb-1.0.so" not found'. DllImport error loading library 'libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0" not found'. DllImport error loading library 'libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0.so" not found'. DllImport error loading library 'usb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/usb-1.0" not found'. DllImport error loading library '/storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0" not found'. DllImport error loading library '/storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//storage/emulated/0/Android/data/RDScanFingerprint.RDScanFingerprint/files/.__override__/libusb-1.0.so" not found'. DllImport error loading library '/system/lib/libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//system/lib/libusb-1.0" not found'. DllImport error loading library '/system/lib/libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm//system/lib/libusb-1.0.so" not found'. DllImport error loading library 'libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0" not found'. DllImport error loading library 'libusb-1.0.so': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0.so" not found'. DllImport error loading library 'libusb-1.0': 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0" not found'. DllImport unable to load library 'dlopen failed: library "/data/app/RDScanFingerprint.RDScanFingerprint-1/lib/arm/libusb-1.0" not found'. 

我知道我做错了什么吗?

如果您使用的是Visual Studio,并且正在向Xamarin移植一些已在Android上运行的JNI-Java代码,请按照以下步骤操作:

  1. 将.so文件放在Xamarin项目的“lib”文件夹下,例如: 在此处输入图像描述
  2. 确保您的.so文件设置为“Build Action”到“Android Native Library”

    • 右键单击.so文件 – >属性 在此处输入图像描述 在此处输入图像描述
  3. 在C#-Xamarin中,您可以按以下方式加载库

     try { JavaSystem.LoadLibrary("SDL2"); JavaSystem.LoadLibrary("glib-2.0"); JavaSystem.LoadLibrary("gthread-2.0"); JavaSystem.LoadLibrary("fluidsynth"); JavaSystem.LoadLibrary("sdl_mixer"); JavaSystem.LoadLibrary("initmixer"); } catch (UnsatisfiedLinkError e) { return e.Message; } 
  4. 必须以下列方式声明C#中的本机方法:

     [DllImport("initmixer", EntryPoint = "Java_sf2Tools_FluidsynthJNI_loadSong")] public static extern int loadSong(IntPtr env, IntPtr thiz, IntPtr songPath, int miliseconds); [DllImport("initmixer", EntryPoint = "Java_sf2Tools_FluidsynthJNI_isPlaying")] public static extern int isPlaying(); [DllImport("initmixer", EntryPoint = "Java_sf2Tools_FluidsynthJNI_pauseAudio")] public static extern void pauseAudio(); [DllImport("initmixer", EntryPoint = "Java_sf2Tools_FluidsynthJNI_resumeAudio")] public static extern void resumeAudio(); [DllImport("initmixer", EntryPoint = "Java_sf2Tools_FluidsynthJNI_stopAudio")] public static extern void stopAudio(); [DllImport("initmixer", EntryPoint = "Java_sf2Tools_FluidsynthJNI_setSoundfonts")] public static extern void setSoundfonts(IntPtr env, IntPtr thiz, IntPtr js); 

在“EntryPoint”字段中,您必须将函数的名称与C / C ++代码中的名称完全相同,通常为Java_your_package_name_YourClassName_YourMethodName。

例如,这是我原来的C ++代码:

 void Java_sf2Tools_FluidsynthJNI_setSoundfonts(JNIEnv * env, jobject this, jstring js) { //Some code } void Java_sf2Tools_FluidsynthJNI_pauseAudio(JNIEnv * env, jobject this) { //Some code } void Java_sf2Tools_FluidsynthJNI_resumeAudio(JNIEnv * env, jobject this) { //Some code } int Java_sf2Tools_FluidsynthJNI_isPlaying(JNIEnv * env, jobject this) { //Some code } void Java_sf2Tools_FluidsynthJNI_stopAudio(JNIEnv * env, jobject this) { //Some code } int Java_sf2Tools_FluidsynthJNI_loadSong(JNIEnv * env, jobject this, jstring songPath) { //Some code } 

或者也许检查通常会让Android Studio知道您的原生函数全名的警告:

在此处输入图像描述

  1. 在C#Xamarin中,有时你不能跳过你在java中执行的参数:JNIEnv * env,或者这样,你应该使用IntPtr作为这个参数的vartype。 例如,为了调用loadSong函数,我使用了以下参数。

C / C ++

 void Java_sf2Tools_FluidsynthJNI_setSoundfonts(JNIEnv * env, jobject this, jstring js) 

C#Xamarin

 fluidsynth.setSoundfonts(JNIEnv.Handle, System.IntPtr.Zero, new Java.Lang.String(getCFGPathFiltered()).Handle); 
  • 注意以“j”开头的C ++参数,例如:jstring,jint,你不能在jstring上使用C#字符串,例如,你应该使用:

jstring – > new Java.Lang.String(“sampleString”)。Handle – > System.IntPtr

jint – > new Java.Lang.Integer(4).Handle – > System.IntPtr