Win 7 x64 上奇怪的 P/Invoke 问题

发布于 2024-10-17 12:55:12 字数 955 浏览 2 评论 0原文

我正在对 gdi32.dll 中的 CreateRectRgn 进行 P/Invoking。此函数的正常 P/Invoke 签名是:

[DllImport("gdi32", SetLastError=true)]
static extern IntPtr CreateRectRgn(int nLeft, int nTop, int nRight, int nBottom);

作为快捷方式,我还定义了此重载:(

[DllImport("gdi32", SetLastError=true)]
static extern IntPtr CreateRectRgn(RECT rc);

[StructLayout(LayoutKind.Sequential)]
struct RECT{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

是的,我知道 CreateRectRgnIndirect,但由于我必须使用函数在 >System.Drawing.Rectangle 和这个 RECT 结构,上面对我来说更有用,因为它不涉及中间变量。)

此重载应该与正常签名相同,因为它应该在进入 CreateRectRgn 时将堆栈置于相同的状态。事实上,在 32 位 Windows XP 上,它可以完美运行。但在 Windows 7 64 位上,该函数返回零,并且 Marshal.GetLastWin32Error() 返回 87,即“参数不正确”。

关于可能出现什么问题有什么想法吗?

I'm P/Invoking to CreateRectRgn in gdi32.dll. The normal P/Invoke signature for this function is:

[DllImport("gdi32", SetLastError=true)]
static extern IntPtr CreateRectRgn(int nLeft, int nTop, int nRight, int nBottom);

As a shortcut, I've also defined this overload:

[DllImport("gdi32", SetLastError=true)]
static extern IntPtr CreateRectRgn(RECT rc);

[StructLayout(LayoutKind.Sequential)]
struct RECT{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

(Yes, I am aware of CreateRectRgnIndirect, but since I must use functions to convert between System.Drawing.Rectangle and this RECT structure, the above is more useful to me, as it doesn't involve an intermediate variable.)

This overload should work identically to the normal signature, since it should put the stack in an identical state at entry to CreateRectRgn. And indeed, on Windows XP, 32-bit, it works flawlessly. But on Windows 7, 64-bit, the function returns zero, and Marshal.GetLastWin32Error() returns 87, which is "The parameter is incorrect."

Any ideas as to what could be the problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

才能让你更想念 2024-10-24 12:55:12

哦。 Microsoft 在 x64 上使用的调用约定与 STDCALL 完全不同。在对 CreateRectRgn 的调用中,堆栈根本不用于参数,它们都是在寄存器中传递的。当我尝试传递 RECT 结构时,它会在堆栈上创建该结构的副本,并将指向该副本的指针放入寄存器中。因此,这个小技巧在64位Windows中根本不起作用。现在我必须检查所有互操作代码并找到我完成此操作的其他位置并将它们全部取出。

Oh. The calling convention Microsoft uses on x64 is totally different from STDCALL. In the call to CreateRectRgn, the stack isn't used for the parameters at all, they're all passed in registers. When I try to pass a RECT structure, it makes a copy of the structure on the stack, and puts a pointer to this copy in a register. Therefore, this little trick won't work at all in 64-bit Windows. Now I've got to go through all my interop code and find other places I've done this and take them all out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文