Today I ran across the need to make full use of the function to query existing settings. To date, I had only pushed data in, I didn't have a need to actually read anything back out.
Where is where it gets fun. The data that is returned is defined as "LPWSTR* ppszwXMLout". Marshaling simple data types in C# isn't terribly hard, but a pointer to a pointer!? Such things are the crazy constructs of a C programmer! After digging around, I found a sample on jaredpar's blog that showed how to marshal a double dereferenced pointer to an integer. I figured getting a string would be similar, except the final step would be to marshal a string, instead of an int. Lucky for me, it really is that simple.
For more on the gory details, I would suggest clicking on the list to jaredpar's blog. He describes the details well, so I won't bother repeating his work. Instead, here is a quick bit of code that shows the difference for dealing with a string instead of an int :
public void queryProxyData()
{
IntPtr outptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
string query = "";
if (DMProcessConfigXML(query, 1, outptr) == 0)
{
// See if we can demarshal that crazy thing!
IntPtr newPtr = (IntPtr)Marshal.PtrToStructure(outptr, typeof(IntPtr));
string xmlData = Marshal.PtrToStringUni(newPtr);
Debug.WriteLine(xmlData);
Marshal.FreeHGlobal(newPtr);
}
Marshal.FreeHGlobal(outptr);
}
Pretty simple, huh? I can safely say this is a much better solution that a previous one that I found!