Проблема с запуском событий в .NET DLL через COM из Delphi - PullRequest
4 голосов
/ 18 августа 2010

У меня проблема с COM-объектами и событиями запуска. У меня есть:

  • DLL, написанная на C # .NET (3.5), которая вызывает события
  • приложение в Delphi5, которое использует DLL в качестве COM-объекта.

Пока все хорошо. События идут так: - в DLL есть 2 события. Один является внутренним и не виден COM. Второй внешний и виден через COM - в DLL также есть функция OnChanged, которая подключается к внутреннему событию и запускает внешнее событие. Таким образом, в основном каждый раз, когда внутреннее событие является триггером, также происходит и внешнее событие. - эта функция OnChanged также видна COM и может вызываться из приложения Delphi

Я использовал это решение , чтобы все заработало, я могу успешно связать процедуру Delphi с событием .NET, но есть одна загвоздка - если я вызову OnChanged из приложения Delphi, все будет замечательно - связанная функция Delphi будет выполняться так же, как и (очевидно) .NET-функция - если DLL вызывает OnChanged из функции обратного вызова в .NET, связанная функция Delphi НЕ будет выполнена.

Итог: если я запускаю внешнее событие из Delphi, все в порядке. Если DLL запускает внутреннее событие, в Delphi ничего не произойдет (хотя наверняка внешнее событие запущено).

Любые идеи высоко ценятся!

1 Ответ

0 голосов
/ 23 февраля 2012

Очень сложно ответить на этот вопрос без отладки реального кода, но я расскажу вам об одной проблеме, с которой я сталкивался в прошлом при взаимодействии с COM.

Одна возможность, которую вы можете захотеть развлечь, заключается в том, что сборщик событий освобождается GC. Когда вы присоединяете событие к объекту, это событие обычно выводит ссылку на атташе, и оба объекта не будут очищены GC, но когда у вас есть COM-объект, GC не обязательно знает об этой ссылке, и он может убрать один из предметов. Я сталкивался с этим в прошлом с автоматизацией Office через .net. Чтобы решить эту проблему, нужно сохранить ссылку на COM-объект и прикрепить к нему.

Например, это плохо:

public class Foo
{
  public Foo(ICOMObject obj)
  {
    obj.Changed += OnChanged;
  }

  private void OnChanged(object arg)
  {
  }
}

Это будет прекрасно работать, если obj является объектом .net. Событие останется подключенным до тех пор, пока на один из объектов останутся ссылки. Однако это не будет работать с COM-объектом. С COM-объектом, событие, кажется, просто перестает работать в какой-то момент времени, обычно довольно быстро.

Вместо этого попробуйте это:

public class Foo
{
  ICOMObject obj;
  public Foo(ICOMObject obj)
  {
    this.obj = obj;
    this.obj.Changed += OnChanged;
  }

  private void OnChanged(object arg)
  {
  }
}

Я не уверен, что это ваша проблема, но это может быть. Удачи!

...