Search code examples
c#pinvokecode-analysis

MSOCAF Verification - P/Invoke should be portable


I have this MSOCAF error's :

As it is declared in your code, parameter 'fDeleteOnRelease' of P/Invoke 'CompoundDocument.CreateILockBytesOnHGlobal(IntPtr, bool, out CompoundDocument.ILockBytes)' will be 1 bytes wide on 32-bit platforms. This is not correct, as the actual native declaration of this API indicates it should be 4 bytes wide on 32-bit platforms. Consult the MSDN Platform SDK documentation for help determining what data type should be used instead of 'bool'.

and this is the code :

 [DllImport("ole32.dll")]
 static extern IntPtr CreateILockBytesOnHGlobal (
    IntPtr hGlobal,
    [MarshalAs(UnmanagedType.U1)] bool fDeleteOnRelease,
    out ILockBytes ppLkbyt);

I search for a data type to use instead of bool but I fail. What's an alternative that is 4 bytes wide?


Solution

  • The native signature for this function, as found on MSDN is:

    WINOLEAPI CreateILockBytesOnHGlobal(
      _In_   HGLOBAL hGlobal,
      _In_   BOOL fDeleteOnRelease,
      _Out_  ILockBytes **ppLkbyt
    );
    

    You have translated this as:

    [DllImport("ole32.dll")]
    static extern IntPtr CreateILockBytesOnHGlobal (
        IntPtr hGlobal,
        [MarshalAs(UnmanagedType.U1)] bool fDeleteOnRelease,
        out ILockBytes ppLkbyt
    );
    

    I see the following problems:

    1. The return value is an HRESULT. That maps to int.
    2. The BOOL parameter is 4 bytes wide. That's the subject of the warning you quote.

    Now, the default marshalling for a bool is as a 4 byte Windows BOOL. So you can fix the declaration like so:

    [DllImport("ole32.dll")]
    static extern int CreateILockBytesOnHGlobal (
        IntPtr hGlobal,
        bool fDeleteOnRelease,
        out ILockBytes ppLkbyt
    );