【问题标题】:calling convention when using 64bit unmanaged callback使用 64 位非托管回调时的调用约定
【发布时间】:2017-09-22 11:23:47
【问题描述】:

我有一个在 C# 代码中使用的非托管处理程序,委托定义如下

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate int Callback (arguments)

它在 32 位版本中运行良好,我在问我在 64 位版本中必须进行哪些更改。包含处理程序的 dll 的 C 标头将所有函数定义为 __stdcall 如果 WIN32 和 __fastcall 如果 WIN64(即 dll 有 32 位和 64 位版本)。但在 NET 文档中,据说不支持 fastcall。我不明白这一切意味着什么,我应该如何更改(或不更改)64 位代码?

【问题讨论】:

  • 使用 32 位版本,因为 64 位版本是 fastcall 并且网络文档说不支持 fastcall。
  • dll 和 C 头文件是我买的硬件附带的,我还没写。所以我知道您的 -1 是针对硬件供应商的。
  • 编写使用 __stdcall 的非托管包装器并转发到 __fastcall 版本(或使用 C++/CLI 立即将这些函数公开为托管函数),反之则用于回调(传递__fastcall 委托给调用__stdcall 托管回调的非托管代码)。如果有很多函数,您可能不想手动执行此操作,因此可能需要一些代码来生成它们。
  • 只有当 32 位版本无法在 64 位 Windows 上运行时才需要所有这些(如果它直接与驱动程序接口可能就是这种情况)。如果可以,只需将您的托管代码编译为“首选 32 位”并专门使用 32 位版本,这会简单得多。
  • 制造商可能根本不关心 .NET 代码与 DLL 的接口。在非托管代码中,这根本不是问题,因为您#include 标头然后离开了。由于调用约定是(预先提供的)标头的一部分,因此无需修改源。如果供应商担心托管代码,他们会自己提供 API。构建硬件和编写驱动程序已经够难了——托管代码是别人的问题。

标签: c# pinvoke 32bit-64bit unmanaged


【解决方案1】:

你不需要做任何事情。以 64 位代码为目标时,调用约定指令将被忽略,因为该体系结构只有一个调用约定。保持代码不变。它适用于 32 位和 64 位编译。

【讨论】:

    猜你喜欢
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    • 2015-11-29
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多