Предоставление управляемого локального COM-сервера - E_NOINTERFACE - PullRequest
0 голосов
/ 02 февраля 2011

Я пытаюсь выставить локальный сервер, написанный на C #, неуправляемому коду, чтобы разрешить взаимодействие!Управляемый код выглядит так:


    [Guid("A0D470AF-0618-40E9-8297-8C63BAF3F1C3")]
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IMyLocalInterface
    {
        void LogToServer(string message);
    }

    [Guid("9E9E5403-7993-49ED-BAFA-FD9A63A837E3")]
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class MyLocalClass : IMyLocalInterface
    {
        public MyLocalClass()
        {
            Console.WriteLine("Object created!");
        }

        public void LogToServer(string message)
        {
            Console.WriteLine("Log > " + message);
        }
    }

    class Program
    {
        [MTAThread]
        static void Main(string[] args)
        {
            var srv = new RegistrationServices();
            var cookie = srv.RegisterTypeForComClients(typeof(MyLocalClass), RegistrationClassContext.LocalServer | RegistrationClassContext.RemoteServer, RegistrationConnectionType.MultipleUse);

            Console.ReadLine();

            srv.UnregisterTypeForComClients(cookie);
        }
    }

А мой неуправляемый код выполняет следующие действия:


#import "ManagedLocServer.tlb" no_namespace raw_interfaces_only

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);
    {
        IMyLocalInterfacePtr ptr;
        ptr.CreateInstance(__uuidof(MyLocalClass));

        ptr->LogToServer(L"Initializing...");

    }
    CoUninitialize();
    return 0;
}

После отладки я увидел, что CoCreateInstance работает без каких-либо проблем, что означает «Объект создан»выводится на консоль управляемых серверов.Но тогда QueryInterface для этого объекта завершается ошибкой с E_NOINTERFACE.Я немного запутался, почему это происходит.Это проблема с регистрацией (у меня есть только запись LocalServer32 для моего CLSID)?Это проблема в моем управляемом коде?Было бы неплохо, если бы кто-нибудь дал мне подсказку:)

Привет, Джо

1 Ответ

2 голосов
/ 02 февраля 2011

Вы используете внепроцессный COM. Это требует поддержки маршалинга, чтобы метод вызывал аргументы метода, которые нужно сериализовать. Обычно это делается путем создания прокси / заглушки DLL из кода, сгенерированного midl.exe из файла .idl. Или с помощью стандартного маршаллера, который работает с библиотекой типов. Оба требуют записи реестра в HKCR \ Interface

Вы получаете E_NOINTERFACE, потому что COM не может найти маршаллера. Это легко решить, если у вас есть файл .idl, но у вас его нет, сервер реализован в .NET. Не знаю, как это решить, я никогда не пытался сделать эту работу. Удаленная возможность состоит в том, что уровень взаимодействия CLR обеспечивает поддержку маршалинга. Но вам наверняка придется использовать ComInterfaceType.InterfaceIsDual. Это всего лишь предположение. Если бы я попытался сделать это, я бы сначала начал с .idl.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...