Reputation: 3833
When using platform invokes, does specifying arguments as [In]
make a difference in how the runtime approaches these?
For instance, when PInvoking CreateRemoteThread
, lpThreadId
is specified as out
as per the article on MSDN:
HANDLE WINAPI CreateRemoteThread(
_In_ HANDLE hProcess,
_In_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_ LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_ LPDWORD lpThreadId
);
And all other arguments are _In_
. In my C# code, I handle that specific function like so:
[DllImport("kernel32.dll", EntryPoint = "CreateRemoteThread", SetLastError = true)]
public static extern IntPtr CreateRemoteThread(
IntPtr hProcess,
IntPtr lpThreadAttributes,
uint dwStackSize,
IntPtr lpStartAddress,
IntPtr lpParameter,
uint dwCreationFlags,
[Out] IntPtr lpThreadId);
Adding the [Out]
attribute to lpThreadId
so the runtime knows to marshal it back to the caller. Would the runtime handle my function any different if I'd change the function signature to this:
[DllImport("kernel32.dll", EntryPoint = "CreateRemoteThread", SetLastError = true)]
public static extern IntPtr CreateRemoteThread(
[In] IntPtr hProcess,
[In] IntPtr lpThreadAttributes,
[In] uint dwStackSize,
[In] IntPtr lpStartAddress,
[In] IntPtr lpParameter,
[In] uint dwCreationFlags,
[Out] IntPtr lpThreadId);
Or would it be the exact same thing; are arguments considered [In]
by default?
Upvotes: 1
Views: 220
Reputation: 5128
The [In]
and [Out]
attributes actually are very important, they tell the framework whether or not it needs to concern itself with marshaling a parameter in a particular direction. This is particularly useful for things like structs
which are very expensive to marshal. By default the framework assumes that marshaling is bidirectional, which may have a large performance impact.
Some of the comments have brought up the fact that primitive types are marshaled as [In]
by default, this is correct. However the fact that marshaling is complicated gives onus to being as explicit as possible in PInvoke declarations, leave as little as possible to the framework to decide even it it is already supposed to be that way.
Upvotes: 5