<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Электронный научно-практический журнал «Современная техника и технологии» &#187; Рыболовлев Дмитрий Александрович</title>
	<atom:link href="http://technology.snauka.ru/author/79208085372/feed" rel="self" type="application/rss+xml" />
	<link>https://technology.snauka.ru</link>
	<description></description>
	<lastBuildDate>Fri, 30 Jan 2026 18:56:12 +0000</lastBuildDate>
	<language>ru</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Особенности использования компонент платформы .NET в рамках модели COM</title>
		<link>https://technology.snauka.ru/2015/09/7776</link>
		<comments>https://technology.snauka.ru/2015/09/7776#comments</comments>
		<pubDate>Sun, 06 Sep 2015 10:23:50 +0000</pubDate>
		<dc:creator>Рыболовлев Дмитрий Александрович</dc:creator>
				<category><![CDATA[Общая рубрика]]></category>
		<category><![CDATA[модель COM]]></category>
		<category><![CDATA[платформа .NET]]></category>

		<guid isPermaLink="false">https://technology.snauka.ru/?p=7776</guid>
		<description><![CDATA[Введение Одной из неприятных особенностей командной разработки проектов может стать проблема сопряжения различных модулей/блоков, написанных разными группами исполнителей. Естественно, вопросы взаимодействия модулей должны быть максимально подробно описаны в техническом задании на разработку (ТЗ), однако даже в этом случае возможны определенные сложности. В статье рассматриваются отдельные вопросы совместимости программных компонентов объектной модели COM (Component Object Model, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><span><strong>Введение<br />
</strong></span></p>
<p style="text-align: justify;"><span>Одной из неприятных особенностей командной разработки проектов может стать проблема сопряжения различных модулей/блоков, написанных разными группами исполнителей. Естественно, вопросы взаимодействия модулей должны быть максимально подробно описаны в техническом задании на разработку (ТЗ), однако даже в этом случае возможны определенные сложности.<br />
</span></p>
<p style="text-align: justify;"><span>В статье рассматриваются отдельные вопросы совместимости программных компонентов объектной модели COM (Component Object Model, модель компонентных объектов) и платформы .NET. Если быть точнее, детально рассматривается одно из решений проблемы использования управляемых (managed, под управлением платформы .NET) библиотек классов языка C#, использующих функциональные возможности платформы .NET, в коде на языке C++ (здесь и далее имеется в виду неуправляемый код C++, unmanaged, под управлением операционной системы).<br />
</span></p>
<p style="text-align: justify;"><span>Все примеры реализованы в среде программирования MS Visual Studio 2012 под управлением ОС Windows 7, платформа .NET версии 4.0.<br />
</span></p>
<p style="text-align: justify;"><span>В статье не приводятся общие сведения о компонентах COM и .NET и их сравнение, поскольку указанные вопросы подробно рассмотрены в справочниках по программированию, например, в замечательных книгах [1], [2] и [3]. Следует ограничиться лишь указанием причин, в соответствии с которыми в той или иной ситуации возможен рассматриваемый случай подключения библиотек классов, написанных на C# с использованием функционала .NET, к проектам на C++.<br />
</span></p>
<p style="text-align: justify;"><span>Во-первых, возможны случаи, когда проект разработки программного обеспечения (ПО) планировался для одной группы разработчиков, а в процессе уточнения технического задания потребовалось включение дополнительных групп исполнителей, использующих другие средства и инструменты разработки. Во-вторых, некоторые неточности или погрешности при составлении ТЗ могут привести к тому, что задание на разработку вспомогательных модулей будет перенаправлено внутри основной группы от одной подгруппы исполнителей к другой подгруппе, использующей отличный язык и/или платформу программирования. Кроме того, в условиях сжатых сроков на выполнение заключительных этапов более рациональным может стать «умышленное» перераспределение задач между подгруппами программистов.<br />
</span></p>
<p style="text-align: justify;"><span>Подобные сценарии могут и не привести к рассматриваемой проблеме, если используемые средства взаимодействия между модулями проекта исключают зависимость от языка и платформы. Однако, на практике так бывает не всегда.<br />
</span></p>
<p style="text-align: justify;"><span>Далее рассматривается практический пример из проекта разработки специализированного ПО, предназначенного для анализа сетевого трафика. На одном из заключительных этапов группе разработчиков потребовалось в кратчайшие сроки добавить возможность оповещения администратора системы по электронной почте при наступлении определенного класса событий. При этом задание на разработку модуля отправки сообщений было поручено исполнителям из подгруппы, специализирующейся на использовании C#, с указанием требования возможности его применения в основном проекте на C++.<br />
</span></p>
<p style="text-align: center;"><span><strong>Реализация взаимодействия компонент .NET и COM<br />
</strong></span></p>
<p style="text-align: justify;"><span>Следует отметить, что существует несколько способов использовать управляемые библиотеки классов из неуправляемого кода C++ [4]. Ниже представлен один из возможных вариантов решения рассматриваемого вопроса, рекомендованный MSDN (Microsoft Developer Network, подразделение компании <a title="Майкрософт" href="https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D0%B9%D0%BA%D1%80%D0%BE%D1%81%D0%BE%D1%84%D1%82">Майкрософт</a>, ответственное за взаимодействие с разработчиками) [5].<br />
</span></p>
<p style="text-align: justify;"><span><strong>Этап 1. </strong>Разработка управляемой библиотеки классов <em>SendMailViaDotNet.DLL</em> (DLL, Dynamic Link Library, динамически подключаемая библиотека).<br />
</span></p>
<p style="text-align: justify;"><span>Для реализации возможности отправки письма по электронной почте используются стандартные классы <em>SmtpClient</em>, <em>MailMessage</em>, <em>MailAddress</em> пространства имен <em>System.Net.Mail</em>. Исходный код библиотеки с комментариями представлен ниже (тип создаваемого проекта в среде Visual Studio – <em>Библиотека классов</em>, язык C#, название – <em>SendMailViaDotNet</em>):<br />
</span></p>
<p><img class="alignnone size-full wp-image-7777 aligncenter" title="Рыболовлев" src="https://technology.snauka.ru/wp-content/uploads/2015/09/Ryibolovlev.png" alt="" width="244" height="189" /><img class="alignnone size-full wp-image-7778 aligncenter" title="Рыболовлев 2" src="https://technology.snauka.ru/wp-content/uploads/2015/09/Ryibolovlev-2.png" alt="" width="571" height="741" /></p>
<p style="text-align: justify;"><span>Библиотека содержит объявление интерфейса <em>IMailer</em> и его реализацию с двумя методами <em>TestMail()</em> и <em>SendMail()</em>. Первый метод используется для быстрого тестирования работы с электронной почтой (для отправки письма используется учетная запись почтового сервиса gmail.com с использованием протокола SSL, Secure Sockets Layer, уровень защищённых сокетов), а второй содержит непосредственно блок кода, отвечающий за подготовку и отправку сообщения.<br />
</span></p>
<p style="text-align: justify;"><span>Чтобы убедиться в работоспособности библиотеки, можно создать минимальный тестовый проект C#:<br />
</span></p>
<p><img class="alignnone size-full wp-image-7779 aligncenter" title="Рыболовлев 3" src="https://technology.snauka.ru/wp-content/uploads/2015/09/Ryibolovlev-3.png" alt="" width="358" height="229" /></p>
<p style="text-align: justify;"><span>В результате выполнения программы будет отправлено письмо на ящик <a href="mailto:WeGpdbnggfTV5T9VLXIL@gmail.com"><em>WeGpdbnggfTV5T9VLXIL@gmail.com</em></a>, в чем можно убедиться с помощью веб-интерфейса gmail.com. Предварительно следует проверить настройки антивируса и брандмауэра на предмет разрешения приложениям обращаться во внешнюю сеть. Кроме того, необходимо разрешить доступ приложениям к электронной почте в настройках безопасности учетной записи gmail.com.<br />
</span></p>
<p style="text-align: justify;"><span><strong>Этап 2. </strong>Подписание сборки строгим именем, построение библиотеки, регистрация сборки в реестре.<strong><br />
</strong></span></p>
<p style="text-align: justify;"><span>Для того, чтобы использовать разработанную библиотеку в рамках модели COM, следует соответствующим образом настроить параметры сборки (assembly) библиотеки в файле <em>AssemblyInfo.cs</em> (рис. 1).<br />
</span></p>
<p style="text-align: center;"><img src="https://technology.snauka.ru/wp-content/uploads/2015/09/090615_1023_1.png" alt="" /><span><br />
</span></p>
<p style="text-align: center;"><span>Рис. 1 – Настройка параметров сборки библиотеки<br />
</span></p>
<p style="text-align: justify;"><span>Необходимо заменить строки<br />
</span></p>
<p><span style="color: black; consolas; 12pt; background-color: white;">[<span style="color: blue;">assembly<span style="color: black;">: <span style="color: #2b91af;">ComVisible<span style="color: black;">(<span style="color: blue;">false<span style="color: black;">)]<br />
</span></span></span></span></span></span></span></p>
<p><span style="color: black; consolas; 12pt; background-color: white;">[<span style="color: blue;">assembly<span style="color: black;">: <span style="color: #2b91af;">AssemblyKeyFile<span style="color: black;">(<span style="color: #a31515;">""<span style="color: black;">)]<br />
</span></span></span></span></span></span></span></p>
<p style="text-align: justify;"><span>на следующие:<br />
</span></p>
<p><span style="color: black; consolas; 12pt; background-color: white;">[<span style="color: blue;">assembly<span style="color: black;">: <span style="color: #2b91af;">ComVisible<span style="color: black;">(<span style="color: blue;">true<span style="color: black;">)]<br />
</span></span></span></span></span></span></span></p>
<p><span style="color: black; consolas; 12pt; background-color: white;">[<span style="color: blue;">assembly<span style="color: black;">: <span style="color: #2b91af;">AssemblyKeyFile<span style="color: black;">(<span style="color: #a31515;">"SendMail.SNK"<span style="color: black;">)]<br />
</span></span></span></span></span></span></span></p>
<p style="text-align: justify;"><span>Параметр <em>ComVisible</em> отвечает за «видимость» сборки с точки зрения модели COM. Параметр <em>AssemblyKeyFile </em>указывает на ключевой файл, используемый для подписания сборки так называемым «строгим» именем.<br />
</span></p>
<p style="text-align: justify;"><span>Строгие имена рекомендуется использовать для того, чтобы однозначно идентифицировать сборку. Сборка со строгим именем создается с помощью закрытого ключа, который соответствует открытому ключу, распространяемому вместе со сборкой. Сборка включает манифест, который содержит имена и контрольные суммы всех включаемых файлов [6].<br />
</span></p>
<p style="text-align: justify;"><span>Сборка со строгим именем содержит текстовое имя, номер версии, дополнительные сведения о языке и языковых параметрах, цифровую подпись и открытый ключ, который соответствует закрытому ключу, используемому для подписи. Таким образом, с помощью открытого ключа, распространяемого вместе со сборкой, становится возможным проверить подпись сборки и тем самым гарантировать её целостность.<br />
</span></p>
<p style="text-align: justify;"><span>Задать строгое имя для сборки можно как в свойствах проекта (вкладка <em>Подписывание</em>), так и с помощью утилиты <em>sn.exe</em>, устанавливаемой вместе с Visual Studio.<br />
</span></p>
<p style="text-align: justify;"><span>Наиболее простой способ запуска утилиты – с использованием <em>Командной строки разработчика для Visual Studio</em> (типовое расположение в главном меню: <em>Пуск &gt; Программы &gt; Microsoft Visual Studio 2012 &gt; Visual Studio Tools &gt; Командная строка разработчика для Visual Studio 2012</em>).<br />
</span></p>
<p style="text-align: justify;"><span>Параметры запуска утилиты:<br />
</span></p>
<p style="text-align: justify;"><span style="color: black; consolas; 12pt; background-color: white;">sn.exe -k SendMail.SNK<br />
</span></p>
<p style="text-align: justify;"><span>Результатом выполнения будет являться созданный ключевой файл <em>SendMail.SNK</em>, содержащий пару открытого и закрытого ключей (рис. 2). Скопировав созданный файл в папку проекта <em>SendMailViaDotNet</em>, необходимо построить (перестроить) решение. При этом закрытый ключ из файла <em>SendMail.SNK</em> будет использован для подписи сборки, а открытый ключ будет включен в сборку для проверки подписи сторонними приложениями.<br />
</span></p>
<p style="text-align: center;"><img src="https://technology.snauka.ru/wp-content/uploads/2015/09/090615_1023_2.png" alt="" /><span><br />
</span></p>
<p style="text-align: center;"><span>Рис. 2 – Создание ключевого файла SendMail.SNK<br />
</span></p>
<p style="text-align: justify;"><span>Для того, чтобы созданная библиотека стала COM-видимой, её необходимо зарегистрировать в реестре с помощью утилиты <em>regasm.exe</em>. Следует отдельно подчеркнуть, что подписание сборки с помощью <em>sn.exe</em> производится на стороне разработчика, а регистрация сборки утилитой <em>regasm.exe</em> осуществляется как на стороне разработчика, так и на стороне клиента.<br />
</span></p>
<p style="text-align: justify;"><span>Наиболее простой способ запуска утилиты <em>regasm.exe</em> – также с использованием <em>Командной строки разработчика</em>. Далее необходимо перейти в папку с созданной библиотекой <em>SendMailViaDotNet.dll</em> и запустить утилиту с параметрами (рис. 3):<br />
</span></p>
<p style="text-align: justify;"><span><span style="color: black; consolas; background-color: white;">RegAsm.exe SendMailViaDotNet.dll /tlb:SendMailViaDotNet.tlb /codebase</span><span><br />
</span></span></p>
<p style="text-align: justify;"><span>Параметр <em>/tlb</em> указывает на необходимость создания библиотеки типов для указанной сборки, содержащей описания доступных типов. Параметр <em>/codebase</em> дополнительно создает в реестре соответствующую запись с указанием пути к файлу сборки, не установленной в глобальном кэше сборок GAC (Global Assembly Cache). Не следует указывать этот параметр, если впоследствии планируется устанавливать сборку в GAC.<br />
</span></p>
<p style="text-align: justify;"><span>При попытке зарегистрировать сборку с параметром <em>/codebase</em>, не подписанную строгим именем, утилита <em>regasm.exe</em> выведет предупреждение <em>RA0000</em> о возможных конфликтах при взаимодействии сборки со сторонними приложениями.<br />
</span></p>
<p style="text-align: center;"><img src="https://technology.snauka.ru/wp-content/uploads/2015/09/090615_1023_3.png" alt="" /><span><br />
</span></p>
<p style="text-align: center;"><span>Рис. 3 – Регистрация сборки в реестре<br />
</span></p>
<p style="text-align: justify;"><span><strong>Этап 3. </strong>Разработка проекта <em>SendMailCPP</em>.<strong><br />
</strong></span></p>
<p style="text-align: justify;"><span>На заключительном этапе необходимо разработать проект C++, импортирующий ранее созданную библиотеку типов <em>SendMailViaDotNet.tlb </em>(тип создаваемого проекта в среде Visual Studio – <em>Консольное приложение Win32</em>, язык C++, название – <em>SendMailCPP</em>). Для этого необходимо использовать директиву <em>#import</em> с указанием полного пути к библиотеке типов:<br />
</span></p>
<p><img class="alignnone size-full wp-image-7780 aligncenter" title="Рыболовлев 4" src="https://technology.snauka.ru/wp-content/uploads/2015/09/Ryibolovlev-4.png" alt="" width="551" height="475" /></p>
<p style="text-align: justify;"><span>Программа инициализирует модель COM; создает указатель на интерфейс <em>IMailer</em>, объявленный в импортируемой библиотеке типов; вызывает описанный в интерфейсе метод тестовой отправки письма <em>TestMail()</em>; выводит результат отправки на экран и освобождает ресурсы.<br />
</span></p>
<p style="text-align: justify;"><span>Перед запуском приложения на клиентской стороне необходимо зарегистрировать библиотеку <em>SendMailViaDotNet.dll</em> с помощью утилиты <em>regasm.exe</em>. Условие наличия утилиты – установленная платформа .NET. При этом, поскольку инструменты разработчика Visual Studio, скорее всего, будут отсутствовать на клиентском компьютере, необходимо запускать <em>regasm.exe</em> с указанием полных путей к файлам (рис. 4). Указание параметров <em>/tlb</em> и <em>/codebase</em> на клиентском компьютере не требуется.<br />
</span></p>
<p style="text-align: center;"><img src="https://technology.snauka.ru/wp-content/uploads/2015/09/090615_1023_4.png" alt="" /><span><br />
</span></p>
<p style="text-align: center;"><span>Рис. 4 – Запуск приложения <em>SendMailCPP.exe</em> на стороне клиента<br />
</span></p>
<p style="text-align: center;"><span><strong>Выводы<br />
</strong></span></p>
<p style="text-align: justify;"><span>Рассмотренное решение реализует на практике возможность использования компонент .NET в рамках модели COM и может быть формализовано в виде последовательности следующих этапов:<br />
</span></p>
<ol>
<li>
<div style="text-align: justify;"><span>Разработка управляемой библиотеки классов на языке C# с использованием функционала платформы .NET.<br />
</span></div>
</li>
<li>
<div style="text-align: justify;"><span>Подписание сборки строгим именем, построение библиотеки, регистрация сборки в реестре.<br />
</span></div>
</li>
<li>
<div style="text-align: justify;"><span>Разработка проекта с неуправляемым кодом на языке C++ с использованием функционала ранее созданной библиотеки классов.<br />
</span></div>
<p style="text-align: justify;"><span>Приведенный пример имеет как положительные особенности, так и недостатки.<br />
</span></p>
<p style="text-align: justify;"><span>К преимуществам рассмотренного подхода можно отнести высокую скорость разработки требуемого функционала, особенно в условиях ограниченного времени. Естественно, подобную ситуацию следует в принципе избегать еще на стадии проектирования, однако в условиях, описанных во введении, приведенное решение имеет право на реализацию.<br />
</span></p>
<p style="text-align: justify;"><span>Основными недостатками следует признать относительную сложность и необходимость соблюдения строгой последовательности действий при реализации. Кроме того, при создании инсталлятора (дистрибутива) необходимо дополнительно включать процедуру регистрации библиотек классов C# на стороне клиента.</span></p>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>https://technology.snauka.ru/2015/09/7776/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
