none
Purpose of MarshalAs RRS feed

  • Question

  • I do a lot of win32 calls in my c#. I usually don't bother with MarshalAs for the DllImport definitions. Are there any benefits at all for using MarshalAs? The drawback I can see is that it just adds more complexity to function definitions with no apparent payoff:

    [DllImport( "kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
    public static extern IntPtr CreateFileW
    ( [MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
      [MarshalAs(UnmanagedType.U4)]     UInt32 dwDesiredAccess,
      [MarshalAs(UnmanagedType.U4)]     UInt32 dwShareMode,
                                        IntPtr lpSecurityAttributes,
      [MarshalAs(UnmanagedType.U4)]     UInt32 dwCreationDisposition,
      [MarshalAs(UnmanagedType.U4)]     UInt32 dwFlagsAndAttributes,
                                        IntPtr hTemplateFile
    );


    • Edited by Dev10110110 Monday, November 12, 2018 5:15 AM
    Monday, November 12, 2018 5:11 AM

Answers

  • MarshalAs is only needed when the type of the parameter, argument, field cannot be correctly deduced from the type given. Generally it is needed on arrays, BOOL and strings. In all other cases the marshaler can figure it out. In your case you would only need it on the string. However since you know the string is Unicode, change the CharSet property on the import to Unicode and you don't really need it either. In fact it isn't doing any good because you are explicitly targeting the Unicode version of the function anyway.

    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Dev10110110 Monday, November 12, 2018 8:04 PM
    Monday, November 12, 2018 2:51 PM
    Moderator

All replies

  • MarshalAs is only needed when the type of the parameter, argument, field cannot be correctly deduced from the type given. Generally it is needed on arrays, BOOL and strings. In all other cases the marshaler can figure it out. In your case you would only need it on the string. However since you know the string is Unicode, change the CharSet property on the import to Unicode and you don't really need it either. In fact it isn't doing any good because you are explicitly targeting the Unicode version of the function anyway.

    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Dev10110110 Monday, November 12, 2018 8:04 PM
    Monday, November 12, 2018 2:51 PM
    Moderator
  • Thanks for that. I will remove the MarshalAs. It remains unclear why bool needs marshalling. Can you please explain? There are plenty of times I don't marshal a BOOL returned from win32, it did not seem to be a problem.

    Monday, November 12, 2018 4:25 PM
  • bool doesn't, BOOL does.

    BOOL in Win32 is defined as an int. When you use 'bool' then the marshaler sends it as single byte. Hence it doesn't work properly with Win32 BOOL. You need to use MarshalAs.Bool for this case.

    "There are plenty of times I don't marshal a BOOL returned from win32, it did not seem to be a problem."

    I've seen code work for years and then suddenly fail because of changes to the runtime. The code is still wrong it just hasn't shown up yet. For a return value you might be able to get away with it since the architecture doesn't support a single byte return value. It'll allocate at least a 4/8 byte value anyway. But you're still effectively reading garbage. The marshaling is wrong irrelevant of how many years it's been working.


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, November 12, 2018 5:21 PM
    Moderator
  • I just looked at my library again, and vast majority of the bool returns are not marshalled. They have in fact worked for many years.

    Perhaps I can speculate for a reason. A 16 bit BOOL TRUE would be 0x01 0x00, and an 8 bit bool TRUE would be 0x01. Since C# only takes the first byte, BOOL then becomes same as bool. I imagine passing a bool from C# into win32 would be a problem if unmarshalled.

    Thanks for clearing it up.

    Monday, November 12, 2018 8:04 PM