[Mono-bugs] [Bug 73012][Nor] New - PINVOKE calls from unmanaged to managed don't marshal arrays

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Fri, 25 Feb 2005 05:04:36 -0500 (EST)


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by ximian.10.christofp@spamgourmet.com.

http://bugzilla.ximian.com/show_bug.cgi?id=73012

--- shadow/73012	2005-02-25 05:04:36.000000000 -0500
+++ shadow/73012.tmp.27660	2005-02-25 05:04:36.000000000 -0500
@@ -0,0 +1,165 @@
+Bug#: 73012
+Product: Mono: Class Libraries
+Version: 1.1
+OS: 
+OS Details: WinXP with MS.NET1.1 and MONO1.1.3
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Normal
+Component: CORLIB
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: ximian.10.christofp@spamgourmet.com               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: PINVOKE calls from unmanaged to managed don't marshal arrays
+
+Marshalling Arrays in calls from unmanaged to managed are not implemented
+In marshal.c  mono_marshal_get_managed_wrapper() is not implemented for 
+ARRAYS in mono, in ms.net it is. 
+
+Steps to reproduce the problem:
+
+1. Write a C# program that calls an unmanaged function and provides a 
+managed callback function. This callback must have an ARRAY argument:
+
+   public delegate int  ManagedCallBackType(
+      Int32       attributes,
+      [In, MarshalAs(UnmanagedType.LPArray, 
+ArraySubType=UnmanagedType.LPStr, SizeParamIndex=0)]
+      string[]    attributeNameList
+      );
+
+   ...
+   ManagedCallBackType  callBack =
+      new ManagedCallBackType(ManagedCallBack);
+   ...
+   UnmanagedCall(str.Length, str, callBack);
+
+see also "Adittional Information" at the end.
+
+2. Create an unmanaged DLL that exports UnmanagedCall() and calls the 
+managed callback:
+
+extern "C" __declspec(dllexport) void WINAPI UnmanagedCall(
+   int			  argc,
+   char			**argv,
+   ManagedDelegateType	  callBack)
+{
+   ...
+   int ret = callBack(argc, argv);
+   ...
+}
+
+see also "Adittional Information" at the end.
+
+
+3. Compile the Program InteropTest.exe and the UnManagedDll.dll:
+a. Run the program with mS.NET: This works.
+b. Run the program with MONO1.1.3: Exception and program exit
+
+Actual Results:
+Exception Dialog pops up:
+"**ERROR**: file marshal.c line 3794 (mono_marshal_get_managed_wrapper): 
+should not be reached. aborting ..."
+
+The console shows additional text:
+"** (InteropTest.exe): WARNING **: array marshaling not implemented"
+
+Expected Results:
+The output of the console should be like this:
+1. We will call the unmanaged function...
+2. Call of the unmanaged function ...
+3. We will call the managed callback ...
+4. Call of the managed delegate.
+5. Callback returned 1
+6. all done.
+
+How often does this happen? 
+Each time.
+
+Additional Information:
+
+################# MainClass.cs ###########################
+using System;
+using System.Runtime.InteropServices;
+
+namespace InteropTest
+{
+   class MainClass
+   {
+   [DllImport("UnManagedDll.dll")]
+   public static extern int UnmanagedCall(
+      int                                             argc,
+      [In, MarshalAs(UnmanagedType.LPArray, 
+ArraySubType=UnmanagedType.LPStr)]
+      string[]                                        argv,
+      ManagedCallBackType                             callBack
+      );
+   
+   public delegate int  ManagedCallBackType(
+      Int32       attributes,
+      [In, MarshalAs(UnmanagedType.LPArray, 
+ArraySubType=UnmanagedType.LPStr, SizeParamIndex=0)]
+      string[]    attributeNameList
+      );
+
+   [STAThread]
+   public static void Main(string[] args)
+   {
+      string[] str   = {"a","b"};
+      ManagedCallBackType  callBack =
+         new ManagedCallBackType(ManagedCallBack);
+      Console.WriteLine("1. Call the unmanaged function...");
+      UnmanagedCall(str.Length, str, callBack);
+      Console.WriteLine("6. All done.");
+   }
+
+   public  static int ManagedCallBack(
+      Int32       numStrings,
+      string[]    strings
+      )
+   {
+      if(strings.Length > 0)
+      {
+         Console.WriteLine(
+            "4. Call of the managed delegate. Number of vars: {0}, Length 
+of Array: {1}, Arr[{2}]={3}",
+            numStrings, strings.Length, strings.Length-1, strings
+[strings.Length-1]);
+      }
+      else
+      {
+         Console.WriteLine("4. Call of the managed delegate.");
+      }
+      return 1;
+   }
+   }
+}
+
+
+############# UnmanagedDll.cpp #####################
+// Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN		
+// Windows Header Files:
+#include <windows.h>
+#include <stdio.h>
+
+
+typedef int (__stdcall * ManagedDelegateType)(
+   int      numStrings,
+   char   **strings
+   );
+
+extern "C" __declspec(dllexport) void WINAPI UnmanagedCall(
+   int					  argc,
+   char				**argv,
+   ManagedDelegateType	  callBack)
+{
+   printf("2. Call of the unmanaged function ...");
+   printf("3. We will call the managed callback ...");
+   int ret = callBack(argc, argv);
+   printf("5. Callback returned %d", ret);
+}