<?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>Undsoft.com &#187; Программирование</title>
	<atom:link href="http://blog.undsoft.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.undsoft.com</link>
	<description>Всякая IT всячина</description>
	<lastBuildDate>Thu, 06 May 2010 17:12:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Как начать программировать?</title>
		<link>http://blog.undsoft.com/programming/how-to-start/</link>
		<comments>http://blog.undsoft.com/programming/how-to-start/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 19:05:06 +0000</pubDate>
		<dc:creator>undsoft</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[для начинающих]]></category>
		<category><![CDATA[наивные посты]]></category>

		<guid isPermaLink="false">http://blog.undsoft.com/?p=845</guid>
		<description><![CDATA[
Пока я учился программированию, у меня никогда не было четкой, осознанной картины того, что я делаю. То что-нибудь одно подучишь, то что-нибудь другое, но никогда не была видна картина &#171;в целом&#187;. Все знания доставались как-то отрывочно. Не было понятно, откуда начинать и куда двигаться. Не было системности.
Для того, чтобы получить эту системность, я поступил в [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;"><a class="picture_header" href="http://blog.undsoft.com/programming/how-to-start/"><img class="size-full wp-image-847 aligncenter" title="how-to-start-programming" src="http://blog.undsoft.com/wp-content/uploads/how-to-start-programming.gif" alt="" width="501" height="100" /></a></p>
<p>Пока я учился программированию, у меня никогда не было четкой, осознанной картины того, что я делаю. То что-нибудь одно подучишь, то что-нибудь другое, но никогда не была видна картина &laquo;в целом&raquo;. Все знания доставались как-то отрывочно. Не было понятно, откуда начинать и куда двигаться. Не было системности.</p>
<p>Для того, чтобы получить эту системность, я поступил в университет. Но, на самом деле, это не слишком помогает. Только пройдя некоторый путь, начинаешь что-то понимать.</p>
<p>Если вы так же не можете понять логики во всем этом сложном мире программирования&nbsp;&mdash; вам сюда. <span id="more-845"></span>Итак, предположим, вы решили стать программистом.</p>
<p>Я расскажу, по какому принципу строится обучение в университете, а потом о том, как бы я советовал начинать изучать программирование.</p>
<br><script type="text/javascript"><!--
google_ad_client = "pub-8060518019241521";
/* 468x60, Второй блог */
google_ad_slot = "4868857930";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
<h3>Университет</h3>
<p>Следует понимать, что в университете преподают &laquo;академическое&raquo; программирование. Как и ко многим другим наукам, преподаваемым в университетах, подход к обучению программирования очень обстоятельный.</p>
<p><strong>Само по себе</strong> программирование, написание кода программ&nbsp;&mdash; не слишком сложный процесс. В этом нет ничего фундаментального. Это скорее навык, как рисование или разговор на иностранном языке. Программированию можно было бы обучать в ПТУ.</p>
<p>То, чему уделяется значительная часть времени в университетах это: во-первых, теория, а во-вторых, все то, сопутствующее, что связано с компьютером. Идеально отучившись по университетской программе, вы будете способны полностью объяснить, как работает компьютер.</p>
<p>И говоря &laquo;полностью&raquo;, я имею ввиду, не только компонентный подход (&laquo;Это видеокарта, а это процессор&raquo;), а и более глубокие уровни (&laquo;Регистры процессора Intel 80386 можно разделить на такие группы&raquo;), вплоть до элементарной базы (&laquo;Диод&nbsp;&mdash; это ...&raquo;).</p>
<p>Вы будете ученым. Приятно знать всю эту информацию, это бывает полезно в работе, но не настолько часто.</p>
<p>Еще университет может дать: навыки работы в команде, планирования сроков, правильной огранизации программы, составлению различных схем, отчетности.</p>
<p>Собственно языки программирования тоже преподаются. Самые разные. Но суть обучения сводится к тому, чтобы <strong>изучить сам язык и его возможности</strong>, а <strong>не научится писать какие-нибудь серьезные программы под конкретную платформ</strong><strong>у.</strong></p>
<p>Я веду к тому, что университет не сделает из вас профессионала в том <strong>навыке</strong> программирования, за который обычно платят деньги. Очень многому придется учиться самостоятельно.</p>
<p style="text-align: center;"><a href="http://blog.undsoft.com/wp-content/uploads/willcodehtmlforfood.jpg"><img class="aligncenter size-full wp-image-853" title="willcodehtmlforfood" src="http://blog.undsoft.com/wp-content/uploads/willcodehtmlforfood.jpg" alt="" width="239" height="270" /></a></p>
<br><script type="text/javascript"><!--
google_ad_client = "pub-8060518019241521";
/* 468x60, Второй блог */
google_ad_slot = "4868857930";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
<h3>Если учится самому</h3>
<p>Первый шаг людей, которые хотят научиться программированию, это обычно покупка какой-нибудь книжки. Например, <em>Бьерн Страуструп&nbsp;&mdash; Язык программирования С++</em>. С++, вообще, почему-то самый популярный язык у новичков.</p>
<p>Разочарование наступает, когда прочитав такую книжку, человек понимает, что по-прежнему далек от программирования реальных программ. Книжка учит языку, но не учит программированию под Windows или любую другую систему.</p>
<p>Конечно, такая книга полезна. <strong>После изучения одного языка программирования, разобраться в других не составляет особого труда.</strong></p>
<p>Однако, если бы я начинал учить кого-то программированию, я бы предложил начать с C#.</p>
<p>Еще было бы неплохо сразу задумать себе какую-нибудь цель&nbsp;&mdash; решить написать какую-нибудь определенную программу.</p>
<p>Знания без применения&nbsp;&mdash; плохо усваиваются. А когда по крупицам реализуешь какую-то сложную идею, это мотивирует и ты незаметно сам для себя осваиваешь новые вещи.</p>
<p>Основная причина, почему я бы рекомендовал С#&nbsp;&mdash; это <strong>возможность постепенного развития</strong>.</p>
<p>Знание языка программирования&nbsp;&mdash; не так важно. Важно то, к чему применять язык программирования&nbsp;&mdash; программный интерфейс той среды, где будет работать программа, различные библиотеки.</p>
<p>Я помню, у меня была проблема, когда после изучения С++ по одной из книг, я не мог перейти к программированию приложений под Windows. Это было ужасно. Я прочел книгу о языке. Переменные, конструкции языка, вывод строк на экран&nbsp;&mdash; все стало довольно просто.</p>
<p>А вот чтобы создать простое &laquo;Hello World&raquo; окно в Windows&nbsp;&mdash; надо было очень постараться. Сразу появляется множество новых непонятных вещей: оконные процедуры, хендлы, сообщения и прочие атрибуты WinAPI. Перестаешь понимать, как это все работает...и забрасываешь обучение.</p>
<p>С# сразу привязан к Windows и прикладному уровню. Начать&nbsp;&mdash; совсем просто. Окна программ создаются с помощью визуального редактора&nbsp;&mdash; это не сложнее работы в Ворде.</p>
<p><a href="http://blog.undsoft.com/wp-content/uploads/visual-studio-perfect-interface.png"><img class="aligncenter size-medium wp-image-850" title="visual-studio-perfect-interface" src="http://blog.undsoft.com/wp-content/uploads/visual-studio-perfect-interface-300x252.png" alt="" width="300" height="252" /></a></p>
<p>Потом программа постепенно обрастает кодом.</p>
<p>Кроме того, C# изначально объектно-ориентирован. Мне было сложно по книге понять, что вобще этот ООП такое. Но на практике понимаешь все довольно быстро.</p>
<p>Кроме того, С#&nbsp;&mdash; новый язык. C# программисты востребованы. Я не говорю, что C#&nbsp;&mdash; идеальный язык, у него есть свои недостатки, но по-моему с него очень хорошо начинать обучение программированию.</p>
<p>Впринципе, C#&nbsp;&mdash; не единственный язык, который удовлетворяет вышеперечисленным требованиям, но мне он нравится больше всех.</p>
<br><script type="text/javascript"><!--
google_ad_client = "pub-8060518019241521";
/* 468x60, Второй блог */
google_ad_slot = "4868857930";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
<h3>Практика</h3>
<p>Чтобы начать программировать, понадобится среда программирования&nbsp;&mdash; Microsoft Visual Studio. Качать варез необязательно, Microsoft предлагает облегченную бесплатную версию&nbsp;&mdash; <a href="http://www.microsoft.com/express/vcsharp">http://www.microsoft.com/express/vcsharp</a>. То, что нужно для обучения.</p>
<p>Если опыта программирования нет вобще&nbsp;&mdash; лучше обзавестись книгой. Просто, чтобы познакомится с основными понятиями в программировании. Переменные, циклы, функции&nbsp;&mdash; все это мало отличается от языка к языку.</p>
<p>Необходимые примеры можно найти в интернете. В интернете вобще можно найти все необходимое. Основной источник информации для Windows программиста -- <a href="http://msdn.microsoft.com/ru-ru/library/default.aspx">библиотека MSDN</a>.</p>
<p>Удачи!</p>
<h2  class="related_post_title">Также посмотрите:</h2><ul class="related_post"><li><a href="http://blog.undsoft.com/programming/export-managed-to-unmanaged/" title="Динамическое подключение C# DLL к C++">Динамическое подключение C# DLL к C++</a></li><li><a href="http://blog.undsoft.com/windows-7/windows-7-update-from-beta-to-release/" title="Windows 7. Обновление с беты до release">Windows 7. Обновление с беты до release</a></li><li><a href="http://blog.undsoft.com/games/good-old-pinball/" title="Старый добрый пинбол">Старый добрый пинбол</a></li><li><a href="http://blog.undsoft.com/webdev/debugging-site-in-ie/" title="Отладка сайтов в старых IE">Отладка сайтов в старых IE</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.undsoft.com/programming/how-to-start/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Динамическое подключение C# DLL к C++</title>
		<link>http://blog.undsoft.com/programming/export-managed-to-unmanaged/</link>
		<comments>http://blog.undsoft.com/programming/export-managed-to-unmanaged/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 10:04:48 +0000</pubDate>
		<dc:creator>undsoft</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[.Net Framework]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[DLL]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[IL]]></category>
		<category><![CDATA[managed код]]></category>

		<guid isPermaLink="false">http://blog.undsoft.com/?p=531</guid>
		<description><![CDATA[
Ууу, сегодня brainstorm тема, специально для тру-програмеров. Не так давно мне понадобилось подключить dll, написанную на C#, к основной программе, которая была написана на unmanaged C++. Оказалось, что сделать это не так-то просто.
На одном из зарубежных сайтов мне удалось найти что-то вроде хака, который позволяет небольшим изменением кода dll-ки сделать ее легко экпортируемой. Без всяких [...]]]></description>
			<content:encoded><![CDATA[<p><a class="picture_header" href="http://blog.undsoft.com/programming/export-managed-to-unmanaged/"><img src="http://blog.undsoft.com/wp-content/uploads/c-sharp-cpp-incompatibility-header.jpg" alt="c-sharp-cpp-incompatibility-header" title="c-sharp-cpp-incompatibility-header" width="421" height="150" class="aligncenter size-full wp-image-609" /></a></p>
<p>Ууу, сегодня brainstorm тема, специально для тру-програмеров. Не так давно мне понадобилось подключить dll, написанную на C#, к основной программе, которая была написана на unmanaged C++. Оказалось, что сделать это не так-то просто.</p>
<p>На одном из зарубежных сайтов мне удалось найти что-то вроде хака, который позволяет небольшим изменением кода dll-ки сделать ее легко экпортируемой. Без всяких там регистраций dll&#39;ки в системе.</p>
<p>Метод не Бог весть что, но для простых дллок работает и в целом заслуживает того, чтобы я о нем написал.<span id="more-531"></span></p>
<br><script type="text/javascript"><!--
google_ad_client = "pub-8060518019241521";
/* 468x60, Второй блог */
google_ad_slot = "4868857930";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
<h2>Вступление</h2>
<p><em>Этот пост&nbsp;&mdash; модифицированный перевод статьи с <a href="http://www.csharphelp.com/archives3/archive500.html">CSharpHelp.com</a>. </em></p>
<p>Предложенный метод работает не только для C# и С++. Тем же самым способом можно добиться взаимодействия любых unmanaged языков и dll, написанных с использованием .Net Framework.</p>
<p>В целом, можно связать managed DLL  и unmanaged программу, используя технологию COM. Но может случится так, что язык, на котором написана ваша основная програма, не поддерживает COM. Или у вас есть любая другая причина не использовать эту технологию, включая нежелание <img src='http://blog.undsoft.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p>Из необходимых инструментов&nbsp;&mdash; вам непременно <strong>понадобится дизассемблер и ассемблер для языка IL</strong>. Обычно, он есть в пакете со средой разработки от Microsoft или в каком-нибудь SDK (вроде Microsoft .NET Framework Software Development Kit). Проверить, есть ли у вас необходимые программы, можно в консоле. Запустите ее, напишите сначала <em>ILAsm </em>и нажмите Enter<em>,</em> а потом <em>Ildasm</em>. Если программы на компьютере есть, вы увидите какой-нибудь вывод в окне консоли.</p>
<p>Код основного приложения может быть на любом языке, который поддерживает динамическое (явное) подключение DLL. Я буду использовать C++, автор в оригинальной статье по своим причинам использовал Blitz3D.</p>
<h2>Приступаем</h2>
<p>Для начала давайте создадим C# DLL&#39;ку с одной простой функцией, которую мы и будем вызывать в основной программе. Она будет называться SayHello ().</p>
<p>В Visual Studio создайте новый проект <em>Class Library</em> и в основной файл допишите нашу функцию. В итоге получится что-то вроде такого:</p>
<p><code>using System;</code></p>
<p><code>namespace HelloWorldDll&lt;br /&gt;<br />
{&lt;br /&gt;<br />
public class HelloWorldClass&lt;br /&gt;<br />
{&lt;br /&gt;<br />
public static string SayHello(string name)&lt;br /&gt;<br />
{&lt;br /&gt;<br />
return ("Hello " + name);&lt;br /&gt;<br />
}&lt;br /&gt;<br />
}&lt;br /&gt;<br />
}</code></p>
<p>Ничего сложного, так? Неймспейс HelloWorldDll, класс HelloWorldClass и один метод у класса&nbsp;&mdash; SayHello.</p>
<p>Все, что наша функция делает&nbsp;&mdash; это принимает строковое значение, добавляет его к строке "Hello "  и возвращает результирующую строку.</p>
<p>Обратите внимание, что класс объявлен как PUBLIC. Хотя автор оригинальной статьи утверждает, что это НЕ обязательно и нет никакой роли ни у public, ни у static, у некоторых людей были проблемы с использованием функций без этих ключевых слов.</p>
<p>В функции используется передача параметров и есть возвращаемое значение только для того, чтобы показать, что передача параметров не представляет особой проблемы. Вы можете использовать любые базовые типы данных вроде byte, short, long, int, string, uint, ulong. И, да, вы даже можете передать структуру в функцию. Просто убедитесь, что поля в структурах совпадают.</p>
<p>Пример:</p>
<p><code>// C#&lt;br /&gt;<br />
public struct SomeStruct&lt;br /&gt;<br />
{&lt;br /&gt;<br />
public int X, Y, Z;&lt;br /&gt;<br />
public string Name;&lt;br /&gt;<br />
public object Obj;&lt;br /&gt;<br />
}//C++&lt;br /&gt;<br />
Struct SomeType{&lt;br /&gt;<br />
int X, Y, Z;&lt;br /&gt;<br />
string Name;&lt;br /&gt;<br />
object Obj;&lt;br /&gt;<br />
};</code></p>
<p>Приведенный пример будет работать, если вы передадите SomeType в функцию в качестве параметра. Единственное ограничение&nbsp;&mdash; функция на .NET не может возвращать структуру в return. В этом случае, передайте структуру в функцию как параметр и заполните ее.</p>
<p>Вот так:</p>
<p><code>// НЕПРАВИЛЬНО&lt;br /&gt;<br />
public SomeStruct DoStuff()&lt;br /&gt;<br />
{&lt;br /&gt;<br />
SomeStruct obj= new SomeStruct();&lt;br /&gt;<br />
obj.X= 0;&lt;br /&gt;<br />
obj.Y= 0;&lt;br /&gt;<br />
obj.Name= "Эта строка никогда не вернется";&lt;br /&gt;<br />
obj.Obj= null;&lt;br /&gt;<br />
return obj;&lt;br /&gt;<br />
}</code></p>
<p><code>// ПРАВИЛЬНО&lt;br /&gt;<br />
// ref = Передача SomeStruct по ссылке (ByRef в VB)&lt;br /&gt;<br />
public void SomeStruct(ref SomeStruct obj)&lt;br /&gt;<br />
{&lt;br /&gt;<br />
obj.X= 0;&lt;br /&gt;<br />
obj.Y= 0;&lt;br /&gt;<br />
obj.Name= "Эта строка вернется.";&lt;br /&gt;<br />
obj.Obj= null;&lt;br /&gt;<br />
}</code></p>
<p>Теперь, когда мы с этим разобрались, вернемся к основному коду нашей дллки. Скомпилируйте ее.</p>
<p>Теперь у вас должен быть файл <strong>HelloWorldDll.dll</strong>.</p>
<br><script type="text/javascript"><!--
google_ad_client = "pub-8060518019241521";
/* 468x60, Второй блог */
google_ad_slot = "4868857930";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
<h2>Погружение</h2>
<p>Теперь у нас есть managed дллка и нам надо связать ее с обычной unmanaged программой. И мы не хотим использовать COM. Главная интрига&nbsp;&mdash; как же мы это сделаем? Ответ находится в волшебном мире IL. Пожалуй, сначала немного теории.</p>
<p>MSIL (MicroSoft Intermediate Language) или IL&nbsp;&mdash; это фактически язык ассемблера на .NET Framework. Он похож на Java Bytecode, по крайней мере функции у них одинаковые. IL&nbsp;&mdash; это низкоуровневый код, в который преобразуются все .Net языки, такие как C#, VB.NET, C++. Затем уже при запуске программы, он на ходу компилируется в машинный код для процессора и выполняется.</p>
<p>Именно IL код обеспечивает взаимодействие вышеназванных языков между собой и теоретически делает программу на .NET платформонезависимой. Все Exe и Dll, полученные после компиляции .Net языков, содержат не настоящий машинный код, а именно код IL + избыточное описание содержимого, которое называется MetaData.</p>
<p>Вот поэтому мы не можем подключить dll обычными способами&nbsp;&mdash; на самом деле там просто нет экспортируемых функций. Вы можете проверить это утилитой DependencyWalker&nbsp;&mdash; она покажет, что C# dll ничего не экпортирует.</p>
<p>Сейчас нам нужно достать IL код. Для этого есть небольшая утилита, которая поставляется с .NET Framework SDK&nbsp;&mdash; <em>IldAsm.exe</em>.  Как подсказывает ее название, она декомпилирует .Net сборку в IL код. Да, вы можете декомпилировать любое .Net приложение обратно в чистый IL код. Хорошо это или плохо? Вам решать. Существует несколько программ, которые усложняют разбор декомпилированного кода. В то же время без возможности простой декомпиляции этой статьи бы не существовало.</p>
<p>К делу.</p>
<p>Нам надо декомпилировать нашу DLL в IL код, отредактировать ее немного, а затем скопилировать обратно в DLL. Чтобы сделать это, откроем командную строку и в директории, где находится наша DLL, напишем:</p>
<p><strong>c:\somedir\ildasm /OUT:HelloWorldDll.il HelloWorldDll.dll</strong></p>
<p>Это создаст два новых файла:</p>
<ul>
<li>HelloWorldDll.il</li>
<li>HelloWorldDll.res</li>
</ul>
<p>Res файл можно удалять, для нашей дллки он не нужен. Обычно он содержит информацию о ресурсах внутри дллки и мог бы понадобиться, если бы библиотека содержала формы или контролсы, но сейчас HelloWorldDll.res можно спокойно удалить.</p>
<p>Откройте файл HelloWorldDll.il в текстовом редакторе. Содержимое похоже на хаос, но на самом деле не все так плохо. Вы можете захотеть почистить код, убрав пустые строки и ненужные комментарии (они начинаются с &laquo;//&raquo;), но это совсем не обязательно. Код и так без проблем скомпилируется обратно в dll, просто после чистки вам будет легче его читать.</p>
<p>Ниже&nbsp;&mdash; то как выглядит наш IL код после чистки:</p>
<p><code>.assembly extern mscorlib&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )&lt;br /&gt;<br />
.ver 1:0:3300:0&lt;br /&gt;<br />
}&lt;br /&gt;<br />
.assembly HelloWorld&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.hash algorithm 0x00008004&lt;br /&gt;<br />
.ver 0:0:0:0&lt;br /&gt;<br />
}&lt;br /&gt;<br />
.module HelloWorld.dll&lt;br /&gt;<br />
.imagebase 0x00400000&lt;br /&gt;<br />
.subsystem 0x00000003&lt;br /&gt;<br />
.file alignment 512&lt;br /&gt;<br />
.corflags 0x00000001.namespace HelloWorldDll&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.class public auto ansi beforefieldinit HelloWorldClass&lt;br /&gt;<br />
extends [mscorlib]System.Object{}&lt;br /&gt;<br />
}.namespace HelloWorldDll&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.class public auto ansi beforefieldinit HelloWorldClass&lt;br /&gt;<br />
extends [mscorlib]System.Object&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.method public hidebysig static string SayHello(string name)&lt;br /&gt;<br />
cil managed&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.maxstack  2&lt;br /&gt;<br />
.locals init (string V_0)&lt;br /&gt;<br />
IL_0000:  ldstr      "Hello "&lt;br /&gt;<br />
IL_0005:  ldarg.0&lt;br /&gt;<br />
IL_0006:  call       string [mscorlib]System.String::Concat&lt;br /&gt;<br />
(string, string)&lt;br /&gt;<br />
IL_000b:  stloc.0&lt;br /&gt;<br />
IL_000c:  br.s       IL_000eIL_000e:  ldloc.0&lt;br /&gt;<br />
IL_000f:  ret&lt;br /&gt;<br />
}.method public hidebysig specialname rtspecialname&lt;br /&gt;<br />
instance void  .ctor() cil managed&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.maxstack  1&lt;br /&gt;<br />
IL_0000:  ldarg.0&lt;br /&gt;<br />
IL_0001:  call       instance void [mscorlib]System.Object::.ctor()&lt;br /&gt;<br />
IL_0006:  ret&lt;br /&gt;<br />
}&lt;br /&gt;<br />
}&lt;br /&gt;<br />
}</code></p>
<p>Разве это не прекрасно? <img src='http://blog.undsoft.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Как вы видите, IL выглядит как настоящий язык программирования. По сути это и есть настоящий язык программирования, поскольку вы можете писать программы прямо в IL, если хотите. В отличие от обычного языка ассемблера, IL использует стеки. Никаких регистриров, все делается через стек и кучу.</p>
<p>Начнем править файл.</p>
<h2>Флаг corflags</h2>
<p>Для начала нужно заменить строку:<br />
<strong>.corflags  0&times;00000001</strong><br />
на<br />
<strong>.corflags 0&times;00000002</strong></p>
<p>Зачем? Это флаг, часть заголовка Common Language Runtime, который говорит ОС, что та имеет дело со сборкой .NET, а не c обычным исполняемым файлом.</p>
<p>По-умолчанию, этот флаг всегда равен <strong>COMIMAGE_FLAGS_ILONLY (0&times;00000001)</strong>, что говорит о том, что сборка содержит только IL код. Никаких вставок unmanaged кода в Exe/Dll нет.</p>
<p><strong>COMIMAGE_FLAGS_ILONLY (0&times;00000001)</strong></p>
<p><em>Приложение содержит только IL код без каких либо вставок нативного unmanaged кода, кроме стартовой заглушки. Поскольку операционные системы, которые умеют работать с Common Language Runtime (такие как Windows XP), игнориуют стартовую заглушку, можно считать, что файл содержит только чистый IL код. Однако, использование этого флага может вызвать некоторые проблемы связанные с</em><em> IlAsm компилятором под Windows Xp. Если этот флаг установлен </em><em>Windows Xp игнорирует не только стартовую заглушку, но и секцию </em><em>.reloc.</em><em> </em></p>
<p>Важная часть здесь&nbsp;&mdash; это то, что Windows XP игнорирует не только стартовую заглушку, но и .reloc секцию. Это означает, что функции, которые мы экспортируем как unmanaged код, не будут правильно загружены. Для того, чтобы решить эту проблему, мы должны поменять этот флаг на <strong>COMIMAGE_FLAGS_32BITSREQUIRED (0&times;00000002)</strong>.</p>
<p><strong>COMIMAGE_FLAGS_32BITSREQUIRED (0&times;00000002)</strong></p>
<p><em>Этот флаг устанавливается, когда исполняемый файл содержит unmanaged код или секция .recloc не пуста.</em></p>
<h2>Добавление функций</h2>
<p>Далее мы должны зарезервировать место в нашей DLL для хранения адреса фукнции. Во время выполнения модуля, оно будет заполнено действительным адресом функции, сейчас же нам надо просто выделить место.</p>
<p>В IL файле может быть специальная секция, которая называется v-Table. Она предназначена для того, чтобы обеспечить экспорт managed методов для unmanaged кода. Содержимое этой таблицы определяется другим полем&nbsp;&mdash; VTableFixups. Идея в том, что v-Table хранит ключ завязанный на определенный метод. Когда программа запускается, благодаря VTableFixups, этот ключ заменяется на реальный адрес метода или &laquo;переходника&raquo;, который обеспечивает соответствие типов.</p>
<p>Мы и воспользуемся этим принципом, чтобы обеспечить взаимодействие нашей дллки и программы. Более детально узнать о v-table можно в оригинальной статье и в <a href="http://books.google.com/books?id=oAcCRKd6EZgC&amp;pg=PA63&amp;lpg=PA63&amp;dq=V-table+IL&amp;source=bl&amp;ots=KzShcJm_9x&amp;sig=Ed7plPOrRWASII7_pC9NYKmoHkA&amp;hl=en&amp;ei=s6_XSfjiFdLt_AazrvDTDQ&amp;sa=X&amp;oi=book_result&amp;ct=result&amp;resnum=1">этой книге</a>.</p>
<p>Вот код IL-файла, который должен получиться у вас в результате:</p>
<p><code>.assembly extern mscorlib&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )&lt;br /&gt;<br />
.ver 1:0:3300:0&lt;br /&gt;<br />
}&lt;br /&gt;<br />
.assembly HelloWorld&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.hash algorithm 0x00008004&lt;br /&gt;<br />
.ver 0:0:0:0&lt;br /&gt;<br />
}&lt;br /&gt;<br />
.module HelloWorld.dll&lt;br /&gt;<br />
.imagebase 0x00400000&lt;br /&gt;<br />
.subsystem 0x00000003&lt;br /&gt;<br />
.file alignment 512// ### ИЗМЕНЕНО #### -&gt; Изменили флаг, чтобы модуль нормально работал с WinXP&lt;br /&gt;<br />
.corflags 0x00000002// ### ИЗМЕНЕНО #### -&gt; Создана запись в таблице V-Table,&lt;br /&gt;<br />
// которая содержит информацию о нашей функции&lt;br /&gt;<br />
.vtfixup [1] int32 fromunmanaged at VT_01&lt;/p&gt;<br />
&lt;p&gt;// ### ИЗМЕНЕНО #### -&gt; Создана запись данных, которая будет хранить&lt;br /&gt;<br />
// виртуальный адрес на нашу функцию&lt;br /&gt;<br />
.data VT_01 = int32(0)&lt;/p&gt;<br />
&lt;p&gt;.namespace HelloWorldDll&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.class public auto ansi beforefieldinit HelloWorldClass&lt;br /&gt;<br />
extends [mscorlib]System.Object{}&lt;br /&gt;<br />
}&lt;/p&gt;<br />
&lt;p&gt;.namespace HelloWorldDll&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.class public auto ansi beforefieldinit HelloWorldClass&lt;br /&gt;<br />
extends [mscorlib]System.Object&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.method public hidebysig static string&lt;br /&gt;<br />
SayHello(string name) cil managed&lt;br /&gt;<br />
{&lt;br /&gt;<br />
// ### ИЗМЕНЕНО #### -&gt; Мы указали, какую VTable нужно использовать для функции&lt;br /&gt;<br />
.vtentry 1 : 1&lt;/p&gt;<br />
&lt;p&gt;// ### ИЗМЕНЕНО #### -&gt; Экспортируем метод в unmanaged код&lt;br /&gt;<br />
// с именем метода - "SayHello"&lt;br /&gt;<br />
.export [1] as SayHello&lt;/p&gt;<br />
&lt;p&gt;.maxstack  2&lt;br /&gt;<br />
.locals init (string V_0)&lt;br /&gt;<br />
IL_0000:  ldstr      "Hello "&lt;br /&gt;<br />
IL_0005:  ldarg.0&lt;br /&gt;<br />
IL_0006:  call       string [mscorlib]System.String::Concat(string, string)&lt;br /&gt;<br />
IL_000b:  stloc.0&lt;br /&gt;<br />
IL_000c:  br.s       IL_000e&lt;/p&gt;<br />
&lt;p&gt;IL_000e:  ldloc.0&lt;br /&gt;<br />
IL_000f:  ret&lt;br /&gt;<br />
}&lt;/p&gt;<br />
&lt;p&gt;.method public hidebysig specialname rtspecialname&lt;br /&gt;<br />
instance void  .ctor() cil managed&lt;br /&gt;<br />
{&lt;br /&gt;<br />
.maxstack  1&lt;br /&gt;<br />
IL_0000:  ldarg.0&lt;br /&gt;<br />
IL_0001:  call       instance void [mscorlib]System.Object::.ctor()&lt;br /&gt;<br />
IL_0006:  ret&lt;br /&gt;<br />
}&lt;br /&gt;<br />
}&lt;br /&gt;<br />
}&lt;/p&gt;<br />
&lt;p&gt;</code></p>
<h2>Завершаем</h2>
<p>Наша DLL готова. Осталось ее скомпилировать. Сделать это можно следующей командой:</p>
<p><strong>c:\somedir\ilasm /OUT:HelloWorldDll.dll HelloWorldDll.il /DLL</strong></p>
<p>После этого вы получите DLL с экпортируемыми в unmanaged код функциями&nbsp;&mdash; их можно будет увидеть в DependencyWalker и без проблем использовать в С++ программе.</p>
<p>Метод, конечно интересный, хотя возможно и несколько корявый. Мне, например, не удалось обеспечить модуль нормальной отладкой.</p>
<p>Ну, а вобще, можно пользоваться. По крайней мере, вы получили массу полезной информации о внутренней структуре .Net приложения.</p>
<p><br><script type="text/javascript"><!--
google_ad_client = "pub-8060518019241521";
/* 468x60, Второй блог */
google_ad_slot = "4868857930";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
<h2  class="related_post_title">Также посмотрите:</h2><ul class="related_post"><li><a href="http://blog.undsoft.com/programming/how-to-start/" title="Как начать программировать?">Как начать программировать?</a></li><li><a href="http://blog.undsoft.com/ppc/pocket-counter/" title="Pocket Counter: счетчик для КПК">Pocket Counter: счетчик для КПК</a></li><li><a href="http://blog.undsoft.com/security/get-ip-from-icq/" title="Как узнать IP адрес по ICQ?">Как узнать IP адрес по ICQ?</a></li><li><a href="http://blog.undsoft.com/games/play-red-alert-2-over-the-internet/" title="Как настроить мультиплеер в Red Alert 2 &#8211; Ultimate Guide">Как настроить мультиплеер в Red Alert 2 &#8211; Ultimate Guide</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.undsoft.com/programming/export-managed-to-unmanaged/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
