How to pinvoke FmtIdToPropStgName properly

24 Views Asked by At

I can't find a working pinvoke declaration for the FmtIdToPropStgName in the Ole32 API.

I've tried this:

internal class Program
{
    [DllImport("ole32.dll", SetLastError = false, ExactSpelling = true)]
    public static extern int FmtIdToPropStgName(Guid pfmtid, [Out, MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder oszName);

    static void Main(string[] args)
    {
        Guid bstrGuid = new Guid("{7018CEB7-2E6A-4061-B7E6-C9FC9C97F594}");
        var stringBuilder = new StringBuilder(100);
        FmtIdToPropStgName(bstrGuid, stringBuilder);
    }
}

But it fires a System.AccessViolationException: 'Attempted to read or write protected memory.'

This is the working example in C++:

int main()
{
    LPCOLESTR bstrGuid = L"{7018CEB7-2E6A-4061-B7E6-C9FC9C97F594}";
    CLSID clsid;
    auto res2 = CLSIDFromString(bstrGuid, &clsid);

    wchar_t buffer[30] = { 0 };
    auto res = ::FmtIdToPropStgName(&clsid, buffer);

    std::wcout << buffer;
}
1

There are 1 best solutions below

0
blit On

I found out what I was doing wrong. I thought it was the StringBuilder but it was the Guid.

Guids must be declared either as ref or using the [MarshalAs(UnmanagedType.LPStruct)] attribute (but not both at the same time).

So the declaration should be:

[DllImport("ole32.dll", SetLastError = false, ExactSpelling = true,  CharSet = CharSet.Unicode)]
public static extern int FmtIdToPropStgName(ref Guid pfmtid, [Out, MarshalAs(UnmanagedType.LPWStr)] System.Text.StringBuilder oszName);