I didn't try your parameters below, but one thing for sure is that when using the string for the LPWSTR*, you must use the [MarshalAs (UnmanagedType.LPWStr)] attribute in the declaration on the string. If you don't, the string will only contain the first character. This is because the default marshaling for the string (at least on my machine) is UnmanagedType.LPStr. So when it hits the 2nd byte of the first wide char it gets the 0 and thinks it's a null terminated string. Just out of curiosity, is there a setting some where to change this default behavior?
Thanks for the MSDN reference. Chad On Fri, 27 Sep 2002 14:47:46 -0400, Oren Novotny <[EMAIL PROTECTED]> wrote: >Chad, > >Have you tried the following definition? You shouldn't need to worry >about memory management at all--that's Interop's job. You also >shouldn't need to declare the exact type, as the types should be >automatically mapped as listed in the MSDN docs[1]. I'm also pretty >sure that the > >[DllImport("urlmon.dll", EntryPoint = "FindMimeFromData")] > public static extern int FindMimeFromData( > IntPtr pBC, > string pwzUrl, > StringBuilder pBuffer, > int cbSize, > string pwzMimeProposed, > int dwMimeFlags, > ref string ppwzMimeOut, > int dwReserved); > > >To use it (I haven't tested it though), you'd use it the same way as >before, except for the buffer, just pass a new stringbuilder and it's >length. > >StringBuilder buffer = new StringBuilder( 100 ); >String nullStr = null; >String output; > >FindMimeFromDataP(IntPtr.Zero, nullStr, buffer, buffer.Length, nullStr, >0, ref output, 0); > >Granted, I haven't tested it, but it should work and won't have to do >any memory management yourself... > >[1] >ms-help://MS.VSCC/MS.MSDNVS/cpguide/html/cpconplatforminvokedatatypes.ht >m > >--Oren > > >> -----Original Message----- >> From: Moderated discussion of advanced .NET topics. [mailto:ADVANCED- >> [EMAIL PROTECTED]] On Behalf Of Chad M. Gross >> Sent: Friday, September 27, 2002 12:36 PM >> To: [EMAIL PROTECTED] >> Subject: PInvoke with an LPWSTR* parameter >> >> I am calling the FindMimeFromData in urlmon and I want to make sure I >> don't >> have any memory leaks on the unmanaged side. I have two versions of >the >> call, one using a ref IntPtr and one using a [MarshalAs >> (UnmanagedType.LPWStr)] ref string to represent the LPWSTR*. My hunch >is >> the latter "MarshalAs" is the appropriate mechanism. >> >> In the case of using the "ref IntPtr", how would I appropriately >delete >> the >> memory allocated for the string on the unmanaged side (even if this is >not >> the best way)? I'm not sure the Marshal.Free functions are doing the >> trick. >> >> In the case of using "[MarshalAs(UnmanagedType.LPWStr)] ref string", a >> copy >> of the LPWSTR* is made and returned through the managed string. It is >my >> understanding that the marshalling process would free the memory >allocated >> for the LPWSTR* parameter on the unmanaged side. Is this correct? >> >> Below is some sample code that uses both calls for illustration: >> >> >> [DllImport("urlmon.dll", EntryPoint = "FindMimeFromData")] >> public static extern int FindMimeFromData1(IntPtr pBC, IntPtr pwzUrl, >> IntPtr pBuffer, int cbSize, IntPtr pwzMimeProposed, int >> dwMimeFlags, >> ref IntPtr ppwzMimeOut, int dwReserved); >> >> [DllImport("urlmon.dll", EntryPoint = "FindMimeFromData")] >> public static extern int FindMimeFromData2(IntPtr pBC, IntPtr pwzUrl, >> IntPtr pBuffer, int cbSize, IntPtr pwzMimeProposed, int >> dwMimeFlags, >> [MarshalAs(UnmanagedType.LPWStr)] ref string ppwzMimeOut, int >> dwReserved); >> >> public static string GetMimeType(byte[] data) { >> >> IntPtr pBC = IntPtr.Zero; >> IntPtr pwzUrl = IntPtr.Zero; >> GCHandle hBuffer = GCHandle.Alloc(data, GCHandleType.Pinned); >> IntPtr pBuffer = hBuffer.AddrOfPinnedObject(); >> IntPtr pwzMimeProposed = IntPtr.Zero; >> >> IntPtr pMimeType = IntPtr.Zero; >> string mimeType1 = null; >> string mimeType2 = null; >> >> try { >> int rc1 = FindMimeFromData1(pBC, pwzUrl, pBuffer, >> data.Length, >> pwzMimeProposed, 0, ref pMimeType, 0); >> int rc2 = FindMimeFromData2(pBC, pwzUrl, pBuffer, >> data.Length, >> pwzMimeProposed, 0, ref mimeType2, 0); >> >> if (rc1 == 0) { >> >> if (pMimeType != IntPtr.Zero) { >> mimeType1 = Marshal.PtrToStringAuto >> (pMimeType); >> >> // free resources allocated for pMimeType >> // ??? >> } >> } >> } >> finally { >> if (hBuffer.IsAllocated) >> hBuffer.Free(); >> } >> >> return mimeType2; >> } >> >> You can read messages from the Advanced DOTNET archive, unsubscribe >from >> Advanced DOTNET, or >> subscribe to other DevelopMentor lists at http://discuss.develop.com. > >You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or >subscribe to other DevelopMentor lists at http://discuss.develop.com. You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.