Как мне обрабатывать параметры var (или ref) в COM-взаимодействии?

У меня есть автономное приложение, которое предоставляет COM-интерфейсы / CoClasses / Enums и т. Д. Один из этих интерфейсов экспортирует следующую функцию:

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

Примечание: Task также отображается как CoClass.
Примечание: Task [вход, выход]

До сих пор мое устаревшее приложение, также написанное на Delphi, могло взаимодействовать с автономным приложением. Считайте это автономное приложение внепроцессным COM-сервером и рассматривайте это устаревшее приложение как клиентское приложение.

Поскольку я переписываю старое приложение (клиент) Delphi на C #, мне приходится использовать COM Interop на C # для связи с этим приложением. Поэтому я использовал tlbimp.exe для преобразования этих COM-интерфейсов в интерфейсы C #.

Этот метод был переведен следующим образом:

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

Как я могу вызвать FindTask и получить результат уже существующей задачи с этой подписью?

Я пробовал это: (Задача типа CoClass)

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

Но компилятор кричал о типе, поскольку с этим типом класса нет перегрузки (переведенный метод получает объект)

Могу я сделать это вместо этого?

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

Как я могу вызвать метод, который ожидает var (in, out) Variant *, поэтому переводится как объект, но на самом деле имеет более точный тип?


person EProgrammerNotFound    schedule 01.07.2015    source источник


Ответы (1)


Мне кажется, что этот параметр действительно является выходным параметром. На самом деле кажется, что вы не пытаетесь что-либо передать. Похоже, что метод возвращает другой объект. Итак, в C # это должно быть:

void FindTask(string TaskId, out object Task);

Тогда вы бы назвали это так:

Вам нужно будет изменить библиотеку типов, чтобы указать семантику.

Если он действительно включен / выключен, вы должны продолжать использовать ref и вызывать метод следующим образом:

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

Или, возможно, передать реальный объект со значимым состоянием, если он так устроен для работы.

person David Heffernan    schedule 01.07.2015
comment
Ты прав, Дэвид. Это должно быть [out, retval]. Я не проектировал это, просто глупо быть [входить, выходить]. Что ж, теперь я не могу ничего изменить ... слишком много проблем с обратной совместимостью, я буду использовать target = null вместо new object(); - person EProgrammerNotFound; 02.07.2015