在 Xamarin.Android 中加载 .so 文件 [英] Load .so file in Xamarin.Android

查看:33
本文介绍了在 Xamarin.Android 中加载 .so 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to convert a Java class to C# in Xamarin.Android.

原来的Java类有这个:

The original Java class have this:

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 库中的方法.我说得对吗?

I think this "native" methods are the methods inside the .so libraries. Am I correct?

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

So, to load those libraries in my Xamarin.Android project, I tried to do this:

[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

And created a folder structure in my project like: project/lib/arm/files.so

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

When I run the project I get lots of errors:

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,并且要将一些已经在 Android 上运行的 JNI-Java 代码移植到 Xamarin,请按照以下步骤操作:

If you are using Visual Studio, and you are porting to Xamarin some JNI-Java code that was already working on Android, follow this Steps:

  1. 将 .so 文件放在 Xamarin 项目的lib"文件夹下,例如:
  2. 确保您的 .so 文件将构建操作"设置为Android 原生库"

  1. Place your .so files under a "lib" folder on your Xamarin project, example:
  2. Make sure that your .so files are set the "Build Action" to "Android Native Library"

  • 右键单击您的 .so 文件 -> 属性

在 C#-Xamarin 中,您可以通过以下方式加载库

In C#-Xamarin you can load your libraries in the following way

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;
}

  • C# 中的本地方法必须按以下方式声明:

  • The native methods in C# must be declarated in the following way:

    [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.

    On the "EntryPoint" field you have to put the name of the function exactly as they was in your C/C++ code normally Java_your_package_name_YourClassName_YourMethodName.

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

    For Example here is my original C++ code:

    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 知道你的原生函数的全名的警告:

    Or maybe check the warnings that usually gives Android Studio to know the full name of your native functions:

    1. 在 C# Xamarin 中,有时您不能跳过在 Java 中执行的参数,例如:JNIEnv * env 或 jobject this,您应该使用 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

      这篇关于在 Xamarin.Android 中加载 .so 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆