PInvoke exists for a good reason, and that reason is that translating unmanaged calls to managed PInvoke calls is difficult and sometimes involves some trial and error. Microsoft have some very general guidelines here but the most important tip is to make sure the length of the datatypes is the same between PInvoke calls and the underlying unmanaged code. If you really have problems, it may be necessary to use the MarshalAs attribute to force the hand of Interop to use the right type.