Help with LibraryImport and custom marshalling
What am I doing wrong here? I am getting a
System.AccessViolationException
when it tries to convert the first string
(DeviceName
) from unmanaged to managed.
Calling code:
5 Replies
why the custom marshaller
because LibraryImport does not generate marshallers for structs yet
this is not correct, you must not mix
Marshal.SizeOf
(or any other Marshal
APIs) with LibraryImport. you want to use sizeof(DISPLAY_DEVICE_Unmanaged)
your DISPLAY_DEVICE_Unmanaged
is not correct either. DISPLAY_DEVICE_Unmanaged
is what gets sent to unmanaged code, but doesn't match the unmanaged definition of DISPLAY_DEVICE
--the C definition is using an inline array (that's what the UnmanagedType.ByValTStr, SizeConst = 32
means) but you are just using a pointer
so you would need to have public fixed ushort DeviceName[16];
. and then copy the string into that buffer directly. the LibraryImport marshallers are not useful for that
i would consider not using LibraryImport for this tbh. for complex structs with members that need marshalling it is a lot of work at the moment. you can keep using it for other methods but this one it'd be easier to keep as DllImportid just use DllImport then lol
rather than having to deal with all this
why?
because Marshal uses the built-in marshalling system
it will give different answers than what you need if you are using LibraryImport
it only 'works' in this case because there are
MarshalAs
on the struct (which LibraryImport does not use yet)
and even then, in this case, it does not give the size of the struct that LibraryImport marshals, because the struct that it actually marshals to (DISPLAY_DEVICE_Unmanaged
) is declared differently (incorrectly for this API, but nonetheless)You can find a correct definition without marshalling here for reference https://github.com/terrafx/terrafx.interop.windows/blob/39a0cf1a35f6e17e8c9f50f926a03596c702b5e1/sources/Interop/Windows/Windows/um/WinUser/Windows.cs#L2915