【发布时间】:2017-06-02 21:11:51
【问题描述】:
我有一个 C# 应用程序,在 Visual Studio 2017 中在“任何 CPU”目标上编译,并禁用了“首选 32 位”选项。在这个应用程序中,我尝试调用 kernel32!GetBinaryType()。在启用“首选 32 位”的情况下运行时,它工作正常。从 C++ 可执行文件以 32 位或 64 位模式运行时,它工作正常。我不确定我在使用 64 位 C# 应用程序时做错了什么。
这是我的 pinvoke 签名:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetBinaryTypeW([MarshalAs(UnmanagedType.LPWStr)] string path, out UInt32 result);
从64位模式调用这个,GetLastError()返回193,根据https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx是
ERROR_BAD_EXE_FORMAT。
我已将一个 64 位调试器附加到我的 C# 应用程序和我的 C++ 应用程序,以确保字符串到达堆栈上正确位置的 GetBinaryTypeW(),并且在我看来确实如此。
我担心我在编组器中遇到了一些微妙的错误。
我的方法有什么问题?
更新
cmets 中引用的问题与这种情况不符。在那个问题中,对LoadLibrary() 的调用失败了,因为它被用来尝试将 32 位 DLL 加载到 64 位进程中。我不想加载任何 DLL。我只是尝试使用 GetBinaryType() 来检查可执行文件的 PE 标头。
【问题讨论】:
-
就您要达到的目标而言不是重复的,但考虑到结果可能是重复的。
-
kernel32.dll也是 64 位二进制文件的名称。在 64 位 Windows 上,C:\Windows\System32\kernel32.dll是 64 位 DLL,C:\Windows\SysWOW64\kernel32.dll是 32 位 DLL。 -
我们看不到检查错误的代码。 minimal reproducible example 在哪里?
-
Windows 不会有错误吧?问题在你的最后。拥抱那个。向我们展示您的 mcve。
标签: c# windows pinvoke marshalling x86-64