Создайте IDispatch .NET COM класс, где контент доступен только во время выполнения - PullRequest
0 голосов
/ 10 августа 2009

В настоящее время я нахожусь в процессе перемещения некоторого кода из нативного C ++ в управляемый C ++ (чистый). Код включает взаимодействие с Windows Active Scripting. В настоящее время наш нативный код обеспечивает класс с именем ObjectDispatch, который реализует IDispatch (используя ATL). Эта реализация класса запрашивает наш собственный нативный класс «Object» во время выполнения, чтобы определить, какие методы и свойства он поддерживает, а затем перенаправляет любые вызовы «IDispatch :: Invoke» к этому «Object».

Я видел примеры использования взаимодействия .NET COM, которые поддерживают 'IDispatch', однако эти реализации были либо получены из IDL, либо были основаны на спецификации. класса .NET, ни один из которых не происходит во время выполнения.

Похоже, что .NET COM-взаимодействие может генерировать реализацию 'IDispatch' во время компиляции, если вы используете следующий атрибут для данного класса:

[ClassInterface(ClassInterfaceType::AutoDispatch)]

Я предполагаю, что мог бы динамически генерировать класс во время выполнения, который поддерживает этот атрибут. Однако, прежде чем я попытаюсь это, мне интересно, если у кого-нибудь есть какие-либо идеи как это может быть достигнуто с помощью аналогичных средств, которые использовались с собственным кодом.

Обратите внимание, что в настоящее время класс 'Object' остается как собственный класс.

1 Ответ

1 голос
/ 22 декабря 2009

Получил официальную обратную связь от Microsoft, которая "может" сработать. Не было времени, чтобы подтвердить, но подумал, что будет хорошей идеей, если кто-то заинтересован.

    [Guid("00020400-0000-0000-c000-000000000046"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IDispatch
    {
        int GetTypeInfoCount();


    ITypeInfo GetTypeInfo(
        [MarshalAs(UnmanagedType.U4)] int iTInfo,
        [MarshalAs(UnmanagedType.U4)] int lcid);

    [PreserveSig]
    int GetIDsOfNames(
        ref Guid riid,
        [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] rgsNames,
        int cNames,
        int lcid,
        [MarshalAs(UnmanagedType.LPArray)] int[] rgDispId);

    [PreserveSig]
    int Invoke(
        int dispIdMember,
        ref Guid riid,
        [MarshalAs(UnmanagedType.U4)] int lcid,
        [MarshalAs(UnmanagedType.U4)] int dwFlags,
        ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams,
        [Out, MarshalAs(UnmanagedType.LPArray)] object[] pVarResult,
        ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo,
        [Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] pArgErr);
}

class IImplimentIDispatch : IDispatch
{
    public IImplimentIDispatch(object o)
        {
             _o = o;
…
...