从 C# .NET (P/Invoke) 调用 IsWowProcess2

Sup*_*JMN 1 .net c# windows pinvoke winapi

我从未在 C# 中创建过 P/Invoke 包装器方法,因为有一种方法可以使用 .NET Framework 类以“托管方式”来实现。

但是,我需要调用 Win32 API 函数,我发现它并不像我想象的那么容易。

IsWowProcess2 中的函数以及从 C++ 调用它的代码在此处说明。

http://www.rudyhuyn.com/blog/2017/12/13/how-to-detect-that-your-x86-application-runs-on-windows-on-arm/

我创建了一个愚蠢的程序来测试它,但当然,它不起作用:

class Program
{
    static void Main(string[] args)
    {
        var result = IsWowProcess2();
    }

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = false, PreserveSig = true)]
    private static extern MyStruct IsWowProcess2();
}

internal class MyStruct
{
    public ushort One { get; set; }
    public ushort Two { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

创建包装方法以及如何调用它的正确方法是什么?

Dav*_*nan 6

首先阅读文档。这给出了签名:

BOOL IsWow64Process2(
  HANDLE hProcess,
  USHORT *pProcessMachine,
  USHORT *pNativeMachine
);
Run Code Online (Sandbox Code Playgroud)

作为一个pinvoke:

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool IsWow64Process2(
    IntPtr process, 
    out ushort processMachine, 
    out ushort nativeMachine
);
Run Code Online (Sandbox Code Playgroud)

我不知道您的尝试从何而来,但它看起来与正确的声明完全不同,事实上,甚至函数的名称也是错误的。互操作编程是关于细节和将一个二进制接口与另一个匹配。您不必发明界面。要传递的参数、函数名称等细节都需要匹配。

你可以这样称呼它:

ushort processMachine;
ushort nativeMachine;
if (!IsWow64Process2(GetCurrentProcess(), out processMachine, out nativeMachine))
    throw new Win32Exception();
Run Code Online (Sandbox Code Playgroud)

您还需要声明GetCurrentProcess. 你可以使用这个:

[DllImport("kernel32.dll")]
private static extern IntPtr GetCurrentProcess();
Run Code Online (Sandbox Code Playgroud)