在PInvoking中将参数声明为[In]时有什么意义吗?

aev*_*tas 1 c# pinvoke marshalling

使用平台调用时,指定参数[In]是否会影响运行时的方法?

例如,当PInvoking CreateRemoteThread,lpThreadId被指定为out按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
);
Run Code Online (Sandbox Code Playgroud)

所有其他论点都是_In_.在我的C#代码中,我像这样处理特定的函数:

    [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);
Run Code Online (Sandbox Code Playgroud)

添加[Out]属性,lpThreadId以便运行时知道将其封送回调用者.如果我将函数签名更改为此,运行时是否会处理我的函数:

    [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);
Run Code Online (Sandbox Code Playgroud)

或者它是完全相同的东西; 是[In]默认考虑的参数?

Mge*_*etz 5

这些[In][Out]属性实际上非常重要,它们告诉框架它是否需要关注在特定方向上编组参数.这structs对于编组非常昂贵的事情特别有用.默认情况下,框架假定编组是双向的,这可能会对性能产生很大影响.

更新:

一些评论提出了这样一个事实,即原始类型[In]默认是封送的,这是正确的.然而,编组很复杂的事实使得在PInvoke声明中尽可能明确地保留,尽可能少地留给框架来决定它是否已经应该是这样的.