我正在将我的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项目目录中?问候。
答案 0 :(得分:0)
不幸的是,来自Xamarin的本地电话没有很好地记录。在github上查看了一些源代码并进行了一些实验后,我发现了这一点
Xamarin不依赖于Jni。你不必担心坚持Jni的做事方式。例如,第一个参数不必是JNIEnv*
类型。此外,您可以简单地将指针而不是jobjects作为函数参数传递。
答案 1 :(得分:0)
将您的“jniLibs”Java-Android contentent文件夹(包括您的.so文件)复制到Xamarin.Android项目下的“lib”文件夹中,例如:
将.so文件的“Build Action”设置为“AndroidNativeLibrary”。
你的方法的签名应该是这样的:
[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);
有关详细信息,请在此处查看我的答案: