如何处理 COM Interop 中的 var(或 ref)参数?

How do I handle var (or ref) parameters in COM Interop?

我有一个公开 COM Interfaces/CoClasses/Enums 等的独立应用程序。其中一个接口导出以下函数:

procedure FindTask(const TaskId: WideString; var Task: OleVariant); safecall;

注意:Task 也暴露为 CoClass
注:Task是[进,出]

到目前为止,我的遗留应用程序(也是用 Delphi 编写的)已经能够与独立应用程序通信。将该独立应用程序视为进程外 COM 服务器,并将此遗留应用程序视为客户端应用程序。

因为我正在用 C# 重写旧的 Delphi 应用程序(客户端),所以我必须在 C# 中使用 COM Interop 来与该应用程序通信。因此,我利用 tlbimp.exe 将那些 COM 接口转换为 C# 接口。

该方法翻译如下:

void FindTask(string, TaskId, ref object Task);

如何调用 FindTask 并接收具有此签名的已存在任务的结果?

我试过这个:(任务是 CoClass 类型)

ScTask target = new CsTask();
scheduler.FindTask("A GUID value", ref target);

但是编译器对类型大喊大叫,因为没有重载 class 类型(翻译后的方法接收一个对象)

我可以这样做吗?

object target = new object();
scheduler.FindTask("A GUID value", ref target);
ScTask translated = (ScTask) target;

如何调用需要 var (in, out) Variant * 的方法,因此翻译为对象,但实际上具有更精确的类型?

在我看来,该参数确实是一个输出参数。您实际上似乎并没有试图传递任何东西。该方法似乎正在返回一个不同的对象。所以在 C# 中它应该是:

void FindTask(string TaskId, out object Task);

然后你可以这样称呼它:

您需要更改类型库以指定语义。

如果它确实是 in/out 那么您将继续使用 ref 并像这样调用方法:

object target = null;
scheduler.FindTask("A GUID value", ref target);
ScTask translated = (ScTask) target;

或者可能传入一个具有有意义状态的实际对象,如果这就是设计的工作方式的话。