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.