Bugzilla – Bug 323900
[PATCH] Marshalling strings as out parameters doesn't work properly.
Last modified: 2008-02-27 13:16:33 UTC
---- Reported by vincent.finn@riverdocs.com 2007-03-23 08:25:56 MST ---- Hi, I have a function exported from a C++ dll, one of the parameters is an out parameter, the code in the dll calls CoTaskMemAlloc() to return a string. The signature is this: void Execute(wchar_t* pIn, int inLength, wchar_t*& pOut, int* pOutLength) I am building using Visual Studio 2005 and there are two options to define this in C#: [DllImport("C:/interop/release/Controller.dll", EntryPoint = "Execute", CharSet = CharSet.Unicode)] private static extern void ExecuteWithIntPtr( [MarshalAs(UnmanagedType.LPWStr)] string commandIn, int inLength, out IntPtr commandOut, out int outLength); [DllImport("C:/interop/release/Controller.dll", EntryPoint = "Execute", CharSet = CharSet.Unicode)] private static extern void ExecuteWithWStr( [MarshalAs(UnmanagedType.LPWStr), In] string commandIn, int inLength, [MarshalAs(UnmanagedType.LPWStr), Out] out string commandOut, out int outLength); The second method is easier to use since the marshaller does all the work and you don't have to free the memory yourself. Both methods work using the .Net Framework (i.e. run from visual studio under IIS), only the second method, ExecuteWithIntPtr(), works properly with mono, ExecuteWithWStr() only returns the first character. Steps to reproduce the problem: 1. Download the attached file. The first project is the dll, the second is the web application. 2. Build them using Visual Studio. (The path to Controller.dll is hardcoded in WebSite1/Default.aspx.cs so this will need to be changed). 3. Run the web site using Visual Studio, when you click the "Test" buttons the will return the same values. 4. Run the web site using mono XSP 2.0 Web Server, the first test will be correct, the second will be incorrect. Actual Results: The broken version of the function only returns 1 character when run under mono, the working version returns the original string repeated 101 times. Expected Results: Both versions should return the original string repeated 101 times. How often does this happen? This happens every time. ---- Additional Comments From vincent.finn@riverdocs.com 2007-03-23 08:26:52 MST ---- Created an attachment (id=171708) Visual studio projects to reproduce the bug Imported an attachment (id=171708) Unknown bug field "cf_op_sys_details" encountered while moving bug <cf_op_sys_details>Xp Sp2</cf_op_sys_details> Unknown operating system unknown. Setting to default OS "Other".
-> runtime
Created attachment 187528 [details] Patch Patch to marshal strings as out params using correct conversion.
The patch seems to remove this part, and doesn't replace it with anything: - } else { - if (mono_marshal_need_free (t, m->piinfo, spec)) { - mono_mb_emit_ldloc (mb, conv_arg); - if (conv == MONO_MARSHAL_CONV_STR_BSTR) - mono_mb_emit_icall (mb, mono_free_bstr); - else - mono_mb_emit_icall (mb, mono_marshal_free); - } + }
Created attachment 188162 [details] Updated patch and tests I restored the logic I accidentally removed. We now free memory the same as we previously did, and also if the parameter is an out param.
This looks ok to check in.
Jonathan, could you check this in ?
-> FIXED.