将Xamarin与jni

时间:2016-05-25 07:21:56

标签: xamarin.android

我正在将我的Android项目移至Xamarin。 Android项目引用外部库libmyencoder.so.以下是它公开的其中一个函数的签名:

JNIEXPORT jint JNICALL encodeData (JNIEnv *, jclass, jlong,
    jobject, jint, jobject, jint);

在Java方面,本机方法声明如下:

static native int encodeData(long handle,
    ByteBuffer input, int inputLen, ByteBuffer output, int maxOutputLen);

在Xamarin文档中,我看到了一些使用dllimport的例子。基于此,我想我可以按如下方式声明我的C#方法:

[DllImport ("myencoder",EntryPoint="encodeData")]
public extern static void encodeData(long handle, ByteBuffer input,
   int inputLen, ByteBuffer output, int maxOutputLen);

这个C#定义是否正确?

令人困惑的是,虽然我已经定义了切入点,但我还没有在任何地方特别提到本机方法的签名。这将是:

(JLjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;I)I

Xamarin引擎是否足够智能以根据方法声明推断出适当的签名?

另外,我会在哪里将libmyencoder.so复制到我的Xamarin项目目录中?问候。

2 个答案:

答案 0 :(得分:0)

不幸的是,来自Xamarin的本地电话没有很好地记录。在github上查看了一些源代码并进行了一些实验后,我发现了这一点 Xamarin不依赖于Jni。你不必担心坚持Jni的做事方式。例如,第一个参数不必是JNIEnv*类型。此外,您可以简单地将指针而不是jobjects作为函数参数传递。

答案 1 :(得分:0)

将您的“jniLibs”Java-Android contentent文件夹(包括您的.so文件)复制到Xamarin.Android项目下的“lib”文件夹中,例如:

enter image description here

将.so文件的“Build Action”设置为“AndroidNativeLibrary”。 enter image description here

你的方法的签名应该是这样的:

[DllImport ("myencoder",EntryPoint="encodeData")]
public extern static void encodeData(IntPtr env, IntPtr class, IntPtr handle, IntPtr input, IntPtr inputLen, IntPtr output, IntPtr maxOutputLen);

您正在使用jint,jlong​​,jobject,因此您不能直接使用C#类型,您必须使用java类型,例如在jint参数中使用,并且您不能跳过如下参数:JNIEnv *,jclass:

并且您必须使用java参数调用您的函数,例如:

Java.Nio.ByteBuffer inputSample = Java.Nio.ByteBuffer.Allocate(10);
Java.Nio.ByteBuffer outputSample = Java.Nio.ByteBuffer.Allocate(10);
System.IntPtr jClassSample = JNIEnv.FindClass(typeof(SomeClass));
Java.Lang.Long handleVal = new Java.Lang.Long(4);
Java.Lang.Integer inputLenVal = new Java.Lang.Integer(4);
Java.Lang.Integer maxOutputLenVal = new Java.Lang.Integer(4);

encodeData(JNIEnv.Handle, jClassSample, handleVal.Handle, inputSample.Handle, inputLenVal.Handle, outputSample.Handle, maxOutputLenVal.Handle);

有关详细信息,请在此处查看我的答案:

Load .so file in Xamarin.Android