Bug 317298 (MONO73012) - PINVOKE calls from unmanaged to managed don't marshal arrays
Summary: PINVOKE calls from unmanaged to managed don't marshal arrays
Status: RESOLVED FIXED
Alias: MONO73012
Product: Mono: Runtime
Classification: Mono
Component: misc (show other bugs)
Version: 1.1
Hardware: Other Other
: P3 - Medium : Normal
Target Milestone: ---
Assignee: Forgotten User vxPDddArjq
QA Contact: Mono Bugs
URL:
Whiteboard:
Keywords: interop, regression_test_needed
Depends on:
Blocks:
 
Reported: 2005-02-25 12:04 UTC by Christof
Modified: 2007-09-15 21:24 UTC (History)
0 users

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Wiest 2007-09-15 19:08:48 UTC


---- Reported by ximian.10.christofp@spamgourmet.com 2005-02-25 05:04:36 MST ----

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);
}



---- Additional Comments From vargaz@gmail.com 2005-02-25 15:11:28 MST ----

-> runtime



---- Additional Comments From vargaz@gmail.com 2005-03-01 14:34:53 MST ----

This should be fixed in SVN.


Unknown bug field "cf_op_sys_details" encountered while moving bug
   <cf_op_sys_details>WinXP with MS.NET1.1 and MONO1.1.3</cf_op_sys_details>
Unknown operating system unknown. Setting to default OS "Other".
Skipping unknown keyword: portability.