Можно ли скрыть родительский класс при экспорте в COM с ComVisible? - PullRequest
2 голосов
/ 05 августа 2011

В библиотеке классов C # (.Net 3.5) у меня есть очень простой класс (некоторые строковые и длинные свойства, без методов), которые наследуются от System.Web.Services.Protocols.SoapHeader .Мой класс помечен как ComVisible (true), потому что мне нужно использовать его в Delphi.

По какой-то неизвестной причине этот класс не может быть создан в Delphi, когда интерфейс класса автоматически экспортируется (он же атрибут ClassInterface(ClassInterfaceType.AutoDispatch)).Я сделал простую программу на C ++, чтобы проверить это, и каждый раз получаю одну и ту же ошибку: 0x80131509 (параметры методов или возвращаемый тип не могут быть вызваны через IDispatch).После некоторых копаний проблема напрямую связана с SoapHeader.Когда я удаляю его или использую в качестве свойства моего класса, все работает нормально.

В C ++ при использовании IDispatch для доступа к моему классу, экспортированному с помощью ClassInterfaceType.None, все работает нормально.Но я не могу передать IDispatch в Delphi, поэтому я ищу способ избежать экспорта библиотеки типов для экспорта содержимого SoapHeader.

Есть ли способ сделать это?Атрибут .Net для информирования экспортера библиотеки типов, чтобы избежать раскрытия родительского класса?Чтобы выставить только часть класса, даже если есть еще вещи?

1 Ответ

4 голосов
/ 05 августа 2011

Объявите интерфейс, чтобы вы могли явно указывать имена членов, видимых для COM-клиентов. Как это:

using System;
using System.Runtime.InteropServices;

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IThingsIWantToExpose {
    void mumble();
    // etc..
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class MyComClass : SomeBaseClass, IThingsIWantToExpose {
    // Actual implementation of the methods
    public void mumble() { }
    // etc, plus everything else that you want to do in the class
    //...
}

Использование ComInterfaceType.InterfaceIsDual позволяет раннее и позднее связывание (IDispatch). ClassInterfaceType.None скрывает членов класса, поэтому базовый класс также не предоставляется. Включая членов System.Object между прочим.

...