Given this method in the c++ ( Gifflen, animated gif producer ):
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) { ... }
And this signature is for access to it:
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); }
Should p / invoke be like this?
[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);
I have a program that basically just tries to access these Init methods.
I successfully load the library: Java.Lang.JavaSystem.LoadLibrary("gifflen");
Then it seems that I'm pointing to the correct method, but it crashes as soon as it enters the method.
I call Init with the same values as in the java demo application (and basically the same values as in all other implementations of this gif encoder, since this is the same code base for all libraries):
var pathForResult = "/storage/sdcard0/giftest/giffleResult.gif"; int optCol = 256, optQuality = 100, optDelay = 4; Giffle.Init (pathForResult , 256, 256, optCol, optQuality, optDelay);
Then I get this crash:
[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)
Am I using my own libraries incorrectly in a Xamarin app?
Binding Code
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); } }
Code for testing
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 ();