Написание COM-серверов для Windows API в C #, с чего начать? - PullRequest
2 голосов
/ 27 февраля 2012

Я пытаюсь написать несколько плагинов для работы с Интерфейсом плагинов брокера сеансов служб терминалов . Я очень свободно говорю на C #, но я не занимался C ++ с конца 90-х годов. Для плагина, который я пишу, я планирую общаться с базой данных, и я предпочел бы использовать System.Data.SqlClient, чтобы говорить с ним, так как я знаю, что все это довольно хорошо. У меня есть Windows SDK , который предоставил мне файл .idl для интерфейса (tssbx.idl). SDK также предоставляет файл заголовка C (tssbx.h) и исходный файл C (tssbx_i.c).

Я никогда прежде не писал COM-сервер, и у меня было много проблем с поиском ресурсов для изучения того, как читать файл IDL и превращать его в C #. Все, что я нахожу, говорит: « Использовать TlbImport », но для этого необходимо, чтобы в IDL находились такие вещи, как блок library, который tssbx.idl не (и не его зависимые) не реализует.

Какой мой лучший вариант:

  1. Найдите инструмент для C #, эквивалентный MIDL для анализа файла .idl в файле .cs.
  2. Изучите IDL (у меня возникли проблемы с поиском хороших руководств для изучения) и напишите все это на C # от руки.
  3. Напишите dll-помощник, используя предоставленные файлы C, и сделайте этот вызов моей dll C # для моих частей .NET.
  4. Переучите C ++, используйте предоставленные файлы .h и .c и используйте CLR для выполнения моих вызовов .NET.
  5. Какой-то другой вариант, о котором я не подумал.

Ответы [ 2 ]

1 голос
/ 27 февраля 2012

Способ сделать то, что вы пытаетесь сделать, - это перевести определения IDL в интерфейсы C #, а затем реализовать эти интерфейсы как классы C #.Вы применяете соответствующие атрибуты (в основном ComVisible , ClassInterface и ProgId ) к классам, которые вы хотите открыть для COM, и используете инструмент regasm длязарегистрируйте свою сборку как COM-сервер.

Перевод IDL в C # на самом деле не так уж и сложен;по большей части он сопоставляется довольно просто из ключевых слов IDL с ключевыми словами C # и / или MarshalAs атрибутами.У меня есть серия постов в блоге о том, как сделать COM-взаимодействие без tlbimp, в том числе о , как читать IDL .Я не знаю ни одного инструмента, в частности, который бы хорошо справлялся с этой задачей, но если он входит в состав Windows SDK, вы всегда должны сначала проверять pinvoke.net на тот случай, если кто-то другой сделает это за вас.

Что касается других ваших вариантов, то 3 и 4 означают примерно одно и то же.Вы не можете вызывать управляемый код напрямую из неуправляемого кода, если это не сделано через COM Interop или библиотеку C ++ в смешанном режиме.В первом случае вам все равно придется решить все проблемы с регистрацией вашей сборки C # в COM для вызова Cll, так что вы можете также пропустить посредника.Во-вторых, вы в основном выполняете вручную те же действия, что и код взаимодействия во время выполнения, и используете язык, с которым вы менее знакомы, для загрузки, что для меня кажется чистым убытком.

Beоднако следует помнить, что загрузка сборок .NET в неуправляемый контекст не всегда возможна;например, управляемые расширения оболочки явно не поддерживаются в Windows 2008. Я не знаю, позволит ли интерфейс TSSBX загружать управляемые сборки как объекты COM или нет, так что вам придется знать об этой возможности.Если вы не можете, тогда ни один из ваших вариантов не сработает, и вам придется вообще избегать использования .NET Framework, использовать другие технологии доступа к базам данных и писать весь проект на неуправляемом C ++.

1 голос
/ 27 февраля 2012

Я отправляю это как ответ, потому что это слишком долго для комментария

Из того, что я собираю, написание таких плагинов в .NET может вызвать проблемы позже - esp.в сценарии, когда необходимо загрузить более одного плагина на основе .NET, а два (или более) плагина используют разные версии .NET (такие проблемы прямо упоминались в контексте расширений оболочки - я просто беру причины изэтот сценарий как основание для моего подозрения ...).

Что касается вашего варианта IDL, он ничего не может реализовать - это язык описания интерфейса .

Я бы предложил использовать что-то похожее на вариант № 3 с некоторыми изменениями:

Реализовать часть .NET в качестве службы Windows и обмениваться данными между C и .NET через IPC - я бы рекомендовал использовать разделяемую память, которая чрезвычайнобыстро и хорошо поддерживается с .NET4.

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