在c++
库(Gifflen, animated gif maker)中给出此方法:
JNIEXPORT jint JNICALL Java_org_jiggawatt_giffle_Giffle_Init(JNIEnv *ioEnv, jobject ioThis,
jstring gifName, jint w, jint h, jint numColors, jint quality, jint frameDelay) { ... }
这个签名可以访问它:
extern "C"
{
JNIEXPORT jint JNICALL Java_org_jiggawatt_giffle_Giffle_Init(JNIEnv *ioEnv,
jobject ioThis, jstring gifName, jint w, jint h, jint numColors, jint quality,
jint frameDelay);
}
p / invoke不应该与那个相似吗?
[DllImport("libgifflen.so", CharSet = CharSet.Ansi)]
public static extern int Java_org_jiggawatt_giffle_Giffle_Init(string gifName, int w,
int h, int numColors, int quality, int frameDelay);
我有一个基本上只是尝试访问Init方法的程序。
我正在成功加载库:Java.Lang.JavaSystem.LoadLibrary("gifflen");
然后我似乎指向了正确的方法,但它一进入方法就会崩溃。
我使用与java演示应用程序中相同的值调用Init(并且与此gif编码器的所有其他实现中的值基本相同,因为这是所有库的相同代码库):
var pathForResult = "/storage/sdcard0/giftest/giffleResult.gif";
int optCol = 256, optQuality = 100, optDelay = 4;
Giffle.Init (pathForResult , 256, 256, optCol, optQuality, optDelay);
然后我就崩溃了:
[mono-rt] at <unknown> <0xffffffff>
[mono-rt] at (wrapper managed-to-native) org.jiggawatt.giffle.Giffle.Java_org_jiggawatt_giffle_Giffle_Init (string,int,int,int,int,int) <IL 0x00046, 0xffffffff>
[mono-rt] at org.jiggawatt.giffle.Giffle.Init (string,int,int,int,int,int) [0x00001] in c:\Users\user.name\Projects\Giffle\Giffle\Giffle.cs:20
[mono-rt]
[mono-rt] Attempting native Android stacktrace:
[mono-rt]
[mono-rt] at Java_org_jiggawatt_giffle_Giffle_Init+19 [0x6433c83c]
[mono-rt] at ???+12272 [0x6467fff0]
[libc] Fatal signal 11 (SIGSEGV) at 0x6f7475d3 (code=1), thread 29670 (myapp.someapp)
我是否在Xamarin应用程序中错误地使用本机库?
绑定代码
using System;
using System.Runtime.InteropServices;
namespace org.jiggawatt.giffle
{
public class Giffle {
public const string GIFFLE_DLL_NAME = "libgifflen.so";
[DllImport(GIFFLE_DLL_NAME, CharSet = CharSet.Ansi)]
public static extern int Java_org_jiggawatt_giffle_Giffle_Init(string gifName, int w, int h, int numColors, int quality, int frameDelay);
[DllImport(GIFFLE_DLL_NAME, CharSet = CharSet.Ansi)]
public static extern void Java_org_jiggawatt_giffle_Giffle_Close();
[DllImport(GIFFLE_DLL_NAME, CharSet = CharSet.Ansi)]
public static extern int Java_org_jiggawatt_giffle_Giffle_AddFrame(int[] inArray);
}
}
测试代码
var external = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
var appPath = System.IO.Path.Combine (external, "giftest");
if (!Directory.Exists (appPath)) {
Directory.CreateDirectory (appPath);
}
var t = "/storage/sdcard0/giftest/result3.gif";
File.Delete (t);
int optCol = 256, optQuality = 100, optDelay = 4;
Giffle.Init (t, 256, 256, optCol, optQuality, optDelay);
var image = Bitmap.CreateBitmap (256, 256, Bitmap.Config.Argb8888);
for (int i = 0; i < 50; i++) {
image = Bitmap.CreateBitmap (256, 256, Bitmap.Config.Argb8888);
image.EraseColor (Color.Argb (255, 255 - i * 4, i * 4, i * 4));
int[] pixelsCopy = new int[image.Width * image.Height];
image.LockPixels ();
image.GetPixels(pixelsCopy, 0, image.Width, 0, 0, image.Width, image.Height);
image.UnlockPixels ();
image.Recycle ();
Giffle.Java_org_jiggawatt_giffle_Giffle_AddFrame (pixelsCopy);
}
Giffle.Java_org_jiggawatt_giffle_Giffle_Close ();
答案 0 :(得分:1)
如果你的c ++代码对这个参数没有任何作用,你只能跳过这个参数“JNIEnv * ioEnv,jobject ioThis”,就像你在java中一样,否则你也应该在函数定义中包含这些参数。而且你不应该使用C#类型,而是使用java类型。
[DllImport("libgifflen.so", EntryPoint = "Java_org_jiggawatt_giffle_Giffle_Init", CharSet = CharSet.Ansi)]
public static extern int Init(IntPtr env, IntPtr thiz, IntPtr gifName, IntPtr w,
IntPtr h, IntPtr numColors, IntPtr quality, IntPtr frameDelay);
按照以下方式调用您的函数:
Init(JNIEnv.Handle, System.IntPtr.Zero, (new Java.Lang.String("Your gif name")).Handle, (new Java.Lang.Integer(w)).Handle,
(new Java.Lang.Integer(h)).Handle, (new Java.Lang.Integer(numColors)).Handle, (new Java.Lang.Integer(quality)).Handle, (new Java.Lang.Integer(frameDelay)).Handle);
也请回答这个问题: