diff --git a/build-tools/jnienv-gen/Generator.cs b/build-tools/jnienv-gen/Generator.cs index a035544dc..d95326a3d 100644 --- a/build-tools/jnienv-gen/Generator.cs +++ b/build-tools/jnienv-gen/Generator.cs @@ -20,6 +20,7 @@ partial class Generator public static int Main (string [] args) { + //System.Diagnostics.Debugger.Launch (); jnienv_g_c = "JniEnvironment.g.c"; jnienv_g_cs = "JniEnvironment.g.cs"; if (args.Length > 0) @@ -308,11 +309,11 @@ static void GenerateNativeMethods (TextWriter o, HandleStyle style) o.WriteLine (); o.WriteLine ("\t\t[DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]"); o.WriteLine ("\t\tinternal static extern unsafe {0} {1} (IntPtr jnienv{2}{3}{4});", - entry.ReturnType.GetMarshalType (style, isReturn: true), + entry.ReturnType.GetMarshalType (style, isReturn: true, isPinvoke: true), GetPinvokeName (entry.Name), entry.Throws ? ", out IntPtr thrown" : "", entry.Parameters.Length != 0 ? ", " : "", - string.Join (", ", entry.Parameters.Select (p => string.Format ("{0} {1}", p.Type.GetMarshalType (style, isReturn: false), Escape (p.Name))))); + string.Join (", ", entry.Parameters.Select (p => string.Format ("{0} {1}", p.Type.GetMarshalType (style, isReturn: false, isPinvoke: true), Escape (p.Name))))); } o.WriteLine ("\t}"); o.WriteLine (); @@ -354,9 +355,10 @@ static void GenerateJniEnv (TextWriter o, string type, string visibility, Handle default: bool is_void = entry.ReturnType.JniType == "void"; for (int i = 0; i < entry.Parameters.Length; i++) { + var p = entry.Parameters [i]; if (i > 0) o.Write (", "); - o.Write ("{0} {1}", entry.Parameters [i].Type.GetManagedType (style, isReturn: false), Escape (entry.Parameters [i].Name)); + o.Write ("{0} {1}", p.Type.GetManagedType (style, isReturn: false), Escape (p.Name)); } o.WriteLine (")"); o.WriteLine ("\t\t{"); @@ -382,7 +384,7 @@ static void GenerateJniEnv (TextWriter o, string type, string visibility, Handle o.Write (", "); if (p.Type.GetManagedType (style, isReturn: false).StartsWith ("out ", StringComparison.Ordinal)) o.Write ("out "); - o.Write (p.Type.GetManagedToMarshalExpression (style, Escape (entry.Parameters [i].Name))); + o.Write (p.Type.GetManagedToMarshalExpression (style, Escape (p.Name))); } o.WriteLine (");"); RaiseException (o, entry, style); @@ -653,8 +655,8 @@ protected TypeInfo (string jniType) JniType = jniType; } - public abstract string GetMarshalType (HandleStyle style, bool isReturn); - public abstract string GetManagedType (HandleStyle style, bool isReturn); + public abstract string GetMarshalType (HandleStyle style, bool isReturn, bool isPinvoke = false); + public abstract string GetManagedType (HandleStyle style, bool isReturn, bool isPinvoke = false); public virtual string[] GetHandleCreationLogStatements (HandleStyle style, string method, string variable) { @@ -681,6 +683,10 @@ public virtual string[] VerifyParameter (HandleStyle style, string variable) class BuiltinTypeInfo : TypeInfo { + /// + /// NOTE: .NET framework can't marshal this + /// + const string JniArgumentValue = "JniArgumentValue*"; string managed; public BuiltinTypeInfo (string jni, string managed) @@ -689,16 +695,31 @@ public BuiltinTypeInfo (string jni, string managed) this.managed = managed; } - public override string GetMarshalType (HandleStyle style, bool isReturn) + public override string GetMarshalType (HandleStyle style, bool isReturn, bool isPinvoke) { + if (isPinvoke && managed == JniArgumentValue) { + return "IntPtr"; + } return managed; } - public override string GetManagedType (HandleStyle style, bool isReturn) + public override string GetManagedType (HandleStyle style, bool isReturn, bool isPinvoke) { + if (isPinvoke && managed == JniArgumentValue) { + return "IntPtr"; + } return managed; } + public override string GetManagedToMarshalExpression (HandleStyle style, string variable) + { + var value = base.GetManagedToMarshalExpression (style, variable); + if (managed == JniArgumentValue) { + value = "(IntPtr) " + value; + } + return value; + } + public override string[] VerifyParameter (HandleStyle style, string variable) { if (managed != "IntPtr") @@ -720,12 +741,12 @@ public BooleanTypeInfo (string jni) { } - public override string GetMarshalType (HandleStyle style, bool isReturn) + public override string GetMarshalType (HandleStyle style, bool isReturn, bool isPinvoke) { return "byte"; } - public override string GetManagedType (HandleStyle style, bool isReturn) + public override string GetManagedType (HandleStyle style, bool isReturn, bool isPinvoke) { return "bool"; } @@ -750,12 +771,12 @@ public StringTypeInfo (string jni) { } - public override string GetMarshalType (HandleStyle style, bool isReturn) + public override string GetMarshalType (HandleStyle style, bool isReturn, bool isPinvoke) { return "string"; } - public override string GetManagedType (HandleStyle style, bool isReturn) + public override string GetManagedType (HandleStyle style, bool isReturn, bool isPinvoke) { return "string"; } @@ -798,12 +819,12 @@ public JniReleaseArrayElementsModeTypeInfo () { } - public override string GetMarshalType (HandleStyle style, bool isReturn) + public override string GetMarshalType (HandleStyle style, bool isReturn, bool isPinvoke) { return "int"; } - public override string GetManagedType (HandleStyle style, bool isReturn) + public override string GetManagedType (HandleStyle style, bool isReturn, bool isPinvoke) { return "JniReleaseArrayElementsMode"; } @@ -839,12 +860,12 @@ public IdTypeInfo (string jni, string type) this.type = type; } - public override string GetMarshalType (HandleStyle style, bool isReturn) + public override string GetMarshalType (HandleStyle style, bool isReturn, bool isPinvoke) { return "IntPtr"; } - public override string GetManagedType (HandleStyle style, bool isReturn) + public override string GetManagedType (HandleStyle style, bool isReturn, bool isPinvoke) { switch (style) { case HandleStyle.SafeHandle: @@ -968,7 +989,7 @@ public ObjectReferenceTypeInfo (string jni, string safeType, string refType) this.refType = refType; } - public override string GetMarshalType (HandleStyle style, bool isReturn) + public override string GetMarshalType (HandleStyle style, bool isReturn, bool isPinvoke) { switch (style) { case HandleStyle.SafeHandle: @@ -981,7 +1002,7 @@ public override string GetMarshalType (HandleStyle style, bool isReturn) return null; } - public override string GetManagedType (HandleStyle style, bool isReturn) + public override string GetManagedType (HandleStyle style, bool isReturn, bool isPinvoke) { switch (style) { case HandleStyle.SafeHandle: @@ -1088,12 +1109,12 @@ public JavaVMPointerTypeInfo (string jni) { } - public override string GetMarshalType (HandleStyle style, bool isReturn) + public override string GetMarshalType (HandleStyle style, bool isReturn, bool isPinvoke) { return "out IntPtr"; } - public override string GetManagedType (HandleStyle style, bool isReturn) + public override string GetManagedType (HandleStyle style, bool isReturn, bool isPinvoke) { return "out IntPtr"; } diff --git a/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs b/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs index 15c056caf..40dfd3de1 100644 --- a/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs +++ b/src/Java.Interop/Java.Interop/JniEnvironment.Types.cs @@ -53,7 +53,7 @@ public static unsafe JniObjectReference FindClass (string classname) __args [0] = new JniArgumentValue (java); IntPtr ignoreThrown; - c = NativeMethods.java_interop_jnienv_call_object_method_a (info.EnvironmentPointer, out ignoreThrown, info.Runtime.ClassLoader.Handle, info.Runtime.ClassLoader_LoadClass.ID, __args); + c = NativeMethods.java_interop_jnienv_call_object_method_a (info.EnvironmentPointer, out ignoreThrown, info.Runtime.ClassLoader.Handle, info.Runtime.ClassLoader_LoadClass.ID, (IntPtr) __args); JniObjectReference.Dispose (ref java); if (ignoreThrown == IntPtr.Zero) { JniObjectReference.Dispose (ref e);