473,378 Members | 1,436 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

How to marshal unmanaged memory for IQueryInfo

Hi all,

I'm trying to write an InfoTip extension for my filetype in explorer
(running on WinXP & W2K). The interface IQueryInfo supports this
feature (with some help from IPersistFile), through the function call
GetInfoTip. GetInfoTip requires that you return a string for the
InfoTip that is allocated off of CoTaskMem, so that the calling
process (Explorer) can deallocate it.

I'm running into some conceptual trouble with implementing this in the
managed world.

I've used the following interface definition:
[ComImport(),
Guid("00021500-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown )]
public interface IQueryInfo
{
int GetInfoTip(
[In] int dwFlags,
[Out, MarshalAs(UnmanagedType.BStr)] out string ppwszTip);
int GetInfoFlags([Out] int pdwFlags);
}
I started by naively returning a string directly:
public int GetInfoTip(int dwFlags, out string ppwszTip)
{
Debug.WriteLine("ShellSupport.GetInfoTip(" + dwFlags + ")");
ppwszTip = "Hello world.";
return 0;
}
and while the infotip shows up briefly, the Explorer promptly crashes
(I assume because it is trying to de-allocate the string.)
So I _read_ the documentation and realized I probably should be doing
this instead:
public int GetInfoTip(int dwFlags, out string ppwszTip)
{
Debug.WriteLine("ShellSupport.GetInfoTip(" + dwFlags + ")");
ppwszTip = Marshal.StringToCoTaskMemAuto("Hello world.");
return 0;
}
but of course, ppwszTip is a *string*, not an *IntPtr*, so this won't
compile. If I change the second argument in the interface to
[Out, MarshalAs(UnmanagedType.BStr)] out IntPtr ppwszTip
then my function isn't entered at all (the COM signature is too
different?)

All told, I'm conceptually stuck, trying to figure out how to return a
..NET System.String that points to unmanaged memory. I don't think
that can be done, but I'm certain that a C# info tip _can_ be written.
What am I missing?

Any help appreciated,
Alan Bahm
ab***@feico.com
Nov 16 '05 #1
2 3014
Alan,
int GetInfoTip(
[In] int dwFlags,
[Out, MarshalAs(UnmanagedType.BStr)] out string ppwszTip);
int GetInfoFlags([Out] int pdwFlags);
}
The return types should be void, unless you really want to explicitly
return the HRESULT, in which case you should add the [PreserveSig]
attribute to the methods.

The string parameter should be an LPWSTR, not a BSTR, so use
UnmanagedType.LPWStr instead.

pdwFlags should be an out parameter. Note that out == [Out] ref, so
using only the [Out] attribute isn't enough.

and while the infotip shows up briefly, the Explorer promptly crashes
(I assume because it is trying to de-allocate the string.)
More likely because your method signatures are incorrect.

If I change the second argument in the interface to
[Out, MarshalAs(UnmanagedType.BStr)] out IntPtr ppwszTip
then my function isn't entered at all (the COM signature is too
different?)


That should work too if you remove the MarshalAs attribute. But the
runtime returns out strings in CoTaskMemAlloc'ed memory by default so
using a string should be easier.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 16 '05 #2
Mattias,

Thank you very much! I didn't realize that the interop takes care of
the string allocation.
You were right - I went back over the signatures, and I got it working
after changing the int return value to void.

Best regards,
Alan
Nov 16 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Eric Hendriks | last post by:
// In an unmanaged DLL the following function must be called: // int VFGeneralize(const BYTE * const * features); // "features" parameter is supposed to be an array of byte arrays. // function is...
9
by: Angel | last post by:
Hi again, I'm trying to call functions from a proprietary DLL but it's turned out to be more difficult than I thought. I have this W32.DLL which was written in C by USPS. They don't provide the...
4
by: Jeff F | last post by:
Any thoughts on correcting this error? Here is the source: // PrjFileInfo.h : Declaration of the CPrjFileInfo #pragma once #include "resource.h" // main symbols #include...
0
by: Johannes Unfried | last post by:
Problem Best practice needed to marshal STL data from managed code to unmanaged code & vice vers Details managed code is written in managed C++ & accesses the unmanaged code (i.e. lives in a...
0
by: Hypnotron | last post by:
>Hello, >Regarding Marshal.AllocHGlobal versus Marshal.AllocCoTaskMem Does anyone >know the circumstances in which one should use one over the other? >...
1
by: sabys | last post by:
I've been noticing a memory leak with the following sample code snippet. Can someone please advise. Have a C# Winforms app with the following code on a button-click event. private void...
0
by: xrxst32 | last post by:
Hello there, I have some doubts about the best practice for using COM automation, the Runtime Callable Wrapper (RCW) and Marshal.ReleaseComObject. So the question is/are: Do I need to release...
0
by: Gareth | last post by:
If I want to move a signed integer array to unmanaged memory I can use the following code: Dim myArray() As Integer Dim myPtr As IntPtr myPtr =...
2
by: O.B. | last post by:
I have operation within a class that marshals the data into a byte array. Below are three different ways that work. Are there any downsides to using one over the the other? public virtual byte...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.