<?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>elwood.su</title>
	<atom:link href="http://elwood.su/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://elwood.su</link>
	<description>Just my blog</description>
	<lastBuildDate>Tue, 17 Aug 2010 17:49:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Настройка JBoss AS 5.1 (часть 2)</title>
		<link>http://elwood.su/?p=269</link>
		<comments>http://elwood.su/?p=269#comments</comments>
		<pubDate>Tue, 17 Aug 2010 17:49:46 +0000</pubDate>
		<dc:creator>elwood</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://elwood.su/?p=269</guid>
		<description><![CDATA[Итак, сегодня мы займемся настройкой портов HTTP, а также настройкой HTTPS. Стандартный бандл JBoss сконфигурирован так, что HTTP привязан к порту 8080, а HTTPS &#8211; к порту 8443. Допустим, нам необходимо настроить сервер так, чтобы использовался 80 порт для HTTP и 443 для HTTPS, причем при заходе на 80 порт сервер перекидывал клиента на порт [...]]]></description>
			<content:encoded><![CDATA[<p>Итак, сегодня мы займемся настройкой портов HTTP, а также настройкой HTTPS. Стандартный бандл JBoss сконфигурирован так, что HTTP привязан к порту 8080, а HTTPS &#8211; к порту 8443. Допустим, нам необходимо настроить сервер так, чтобы использовался 80 порт для HTTP и 443 для HTTPS, причем при заходе на 80 порт сервер перекидывал клиента на порт HTTPS. Для этого необходимо внести следующие изменения в конфигурационные файлы:</p>
<p>/server/default/conf/bindingservice.beans/META-INF/bindings-jboss-beans.xml (заменяем в трех местах &#8211; первые два определяют порты по умолчанию, третье место определяет XSLT-преобразование, которое применяется для конфигурационного файла server.xml.) У меня эти три места были приведены к следующему виду:</p>
<p>&lt;bean&gt;<br />
&lt;property name=&#8221;serviceName&#8221;&gt;jboss.web:service=WebServer&lt;/property&gt;<br />
&lt;property name=&#8221;port&#8221;&gt;80&lt;/property&gt;<br />
&lt;property name=&#8221;description&#8221;&gt;JBoss Web HTTP connector socket; also drives the values for the HTTPS and AJP sockets&lt;/property&gt;</p>
<p>&lt;bean&gt;<br />
&lt;property name=&#8221;serviceName&#8221;&gt;jboss.web:service=WebServer&lt;/property&gt;<br />
&lt;property name=&#8221;bindingName&#8221;&gt;HttpsConnector&lt;/property&gt;<br />
&lt;property name=&#8221;port&#8221;&gt;443&lt;/property&gt;<br />
&lt;property name=&#8221;description&#8221;&gt;JBoss Web HTTPS connector socket&lt;/property&gt;<br />
&lt;/bean&gt;</p>
<p>&lt;Connector&gt;<br />
&lt;xsl:for-each select=&#8221;@*&#8221;&gt;<br />
&lt;xsl:choose&gt;<br />
&lt;xsl:when test=&#8221;(name() = &#8216;port&#8217; and . = &#8217;80&#8242;)&#8221;&gt;<br />
&lt;xsl:attribute name=&#8221;port&#8221;&gt;&lt;xsl:value-of select=&#8221;$port&#8221; /&gt;&lt;/xsl:attribute&gt;<br />
&lt;/xsl:when&gt;<br />
&lt;xsl:when test=&#8221;(name() = &#8216;port&#8217; and . = &#8217;8009&#8242;)&#8221;&gt;<br />
&lt;xsl:when test=&#8221;(name() = &#8216;redirectPort&#8217;)&#8221;&gt;<br />
&lt;xsl:attribute name=&#8221;redirectPort&#8221;&gt;&lt;xsl:value-of select=&#8221;$portHttps&#8221; /&gt;&lt;/xsl:attribute&gt;<br />
&lt;/xsl:when&gt;<br />
&lt;xsl:when test=&#8221;(name() = &#8216;port&#8217; and . = &#8217;443&#8242;)&#8221;&gt;<br />
&lt;xsl:attribute name=&#8221;port&#8221;&gt;&lt;xsl:value-of select=&#8221;$portHttps&#8221; /&gt;&lt;/xsl:attribute&gt;<br />
&lt;/xsl:when&gt;<br />
&lt;xsl:otherwise&gt;</p>
<p>2. /server/default/deploy/jbossweb.sar/server.xml</p>
<p>Здесь для наших настроек самое главное будет выглядеть так:</p>
<p>&lt;!&#8211; A HTTP/1.1 Connector on port 8080 &#8211;&gt;<br />
&lt;Connector protocol=&#8221;HTTP/1.1&#8243; port=&#8221;80&#8243; address=&#8221;${jboss.bind.address}&#8221;<br />
connectionTimeout=&#8221;20000&#8243; redirectPort=&#8221;443&#8243; /&gt;</p>
<p>&lt;!&#8211; A AJP 1.3 Connector on port 8009 &#8211;&gt;<br />
&lt;Connector protocol=&#8221;AJP/1.3&#8243; port=&#8221;8009&#8243; address=&#8221;${jboss.bind.address}&#8221;<br />
redirectPort=&#8221;443&#8243; /&gt;</p>
<p>&lt;!&#8211; SSL/TLS Connector configuration using the admin devl guide keystore&#8211;&gt;<br />
&lt;Connector protocol=&#8221;HTTP/1.1&#8243; SSLEnabled=&#8221;true&#8221;<br />
port=&#8221;443&#8243; address=&#8221;${jboss.bind.address}&#8221;<br />
scheme=&#8221;https&#8221; secure=&#8221;true&#8221; clientAuth=&#8221;false&#8221;<br />
keystoreFile=&#8221;${jboss.server.home.dir}/conf/mykeystore&#8221;<br />
keystorePass=&#8221;qwerty&#8221; sslProtocol = &#8220;TLS&#8221; /&gt;</p>
<p>Здесь keystore-путь к файлу, содержащему ключи, необходимые для работы HTTPS. Если у вас такого файла нет, вы можете сгенерировать самоподписанный сертификат с использованием стандартной джавовой тулзы keytool (лежит в директории bin в JDK) следующей командой:</p>
<p>&lt;blockquote&gt;keytool –genkey –alias jboss –keypass qwerty –keyalg RSA –keystore mykeystore –validity 3650&lt;/blockquote&gt;</p>
<p>Соответственно, keystorePass- пароль для этой связки ключей.</p>
<p>Интересно, что если сконфигурировать server.xml, но оставить bindings-jboss-beans.xml таким же, то JBoss запустится, но порты будут использованы не те. Не только у меня это вызывает недоумение, но, судя по топику http://community.jboss.org/message/540960?tstart=0, это решение (выполнение дополнительного XSLT преобразования над server.xml) было продиктовано исторически, и в данный момент уже не является чем-то необходимым. Поэтому, скорее всего, в следующих версиях JBoss AS такого дублирования не будет.</p>
<p>Итак, осталось только исправить на всякий случай еще один конфиг, использующий порты 8080 и 8443 &#8211; /server/default/deployers/jbossws.deployer/META-INF/jboss-beans.xml :</p>
<p>&lt;!&#8211;<br />
Set these properties to explicitly define the ports that will be used for rewriting the SOAP address.<br />
Otherwise the ports will be identified by querying the list of installed connectors.<br />
If multiple connectors are found the port of the first connector is used.&#8211;&gt;<br />
&lt;property name=&#8221;webServiceSecurePort&#8221;&gt;443&lt;/property&gt;<br />
&lt;property name=&#8221;webServicePort&#8221;&gt;80&lt;/property&gt;<br />
&lt;/bean&gt;</p>
<p>Последний шаг &#8211; для каждого WAR указать в дескрипторе web.xml на необходимость использования именно защищенного HTTPS протокола. Для этого в web.xml необходимо добавить строки:</p>
<p>&lt;security-constraint&gt;<br />
&lt;web-resource-collection&gt;<br />
&lt;web-resource-name&gt;Protected Context&lt;/web-resource-name&gt;<br />
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />
&lt;/web-resource-collection&gt;<br />
&lt;user-data-constraint&gt; &lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;<br />
&lt;/user-data-constraint&gt;<br />
&lt;/security-constraint&gt;</p>
<p>В первую очередь это можно проверить на встроенных админ-панельках джейбосса (ROOT.war, admin-console.war и тд).</p>
]]></content:encoded>
			<wfw:commentRss>http://elwood.su/?feed=rss2&amp;p=269</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Настройка JBoss AS 5.1 (часть 1)</title>
		<link>http://elwood.su/?p=265</link>
		<comments>http://elwood.su/?p=265#comments</comments>
		<pubDate>Mon, 16 Aug 2010 16:42:27 +0000</pubDate>
		<dc:creator>elwood</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[5.1]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[jbossas]]></category>
		<category><![CDATA[jpda]]></category>

		<guid isPermaLink="false">http://elwood.su/?p=265</guid>
		<description><![CDATA[На днях подумал о том, что было бы неплохо написать несколько постов на тему настройки, использования и разработки на базе платформы JBoss, тем более что уже имеется некий опыт этих манипуляций. Пока, пожалуй, будем говорить о JBoss Application Server 5.1, возможно, чуть позже затронем тему JBoss AS 6 и JBoss Portal, но пока ограничимся Application [...]]]></description>
			<content:encoded><![CDATA[<p>На днях подумал о том, что было бы неплохо написать несколько постов на тему настройки, использования и разработки на базе платформы JBoss, тем более что уже имеется некий опыт этих манипуляций. Пока, пожалуй, будем говорить о JBoss Application Server 5.1, возможно, чуть позже затронем тему JBoss AS 6 и JBoss Portal, но пока ограничимся Application Server&#8217;ом версии 5.1 GA. Это стабильная версия, ее можно скачать на официальном сайте jboss.org.</p>
<p>Итак, для настройки JBoss AS для разработки и использования в продакшене обычно требуется:<br />
1. Настройка режима отладки JPDA<br />
1. Настройка портов, на которые будут биндиться сервисы и HTTP-коннекторы.<br />
2. Настройка админок так, чтобы анонимусы не могли ими воспользоваться<br />
3. Настройка различных сервисов (например, сервис отправки email)<br />
4. Тюнинг текущей конфигурации (отключение ненужных сервисов, изменение настроек)</p>
<p>По порядку эти вещи делать не обязательно, поскольку JBoss AS распространяется в зипованном бандле, который запускается &#8220;здесь и сейчас&#8221;, поэтому я буду описывать эти несложные, в общем-то, вещи, отдельно, в виде небольших шпаргалок.</p>
<p>Итак, начнем с настройки режима отладки JBoss.<br />
Первым делом разработчик, который начал использовать JBoss, хочет заглянуть в свое приложение отладчиком. Для того, чтобы JBoss поддерживал возможность отладки, необходимо поправить файл run.bat, добавив туда опции для виртуальной машины. (В линуксе этим файлом будет, соответственно, run.sh) Я обычно копирую run.bat в run_jpda.bat и добавляю требуемые параметры после, например, этих строк:</p>
<p>if &#8220;x%JAVA_OPTS%&#8221; == &#8220;x&#8221; (<br />
  set &#8220;JAVA_OPTS=-Dprogram.name=%PROGNAME%&#8221;<br />
) else (<br />
  set &#8220;JAVA_OPTS=-Dprogram.name=%PROGNAME% %JAVA_OPTS%&#8221;<br />
)</p>
<p>Дописываем после них</p>
<p>set &#8220;JAVA_OPTS=%JAVA_OPTS% -Xdebug -Xrunjdwp:transport=dt_shmem,address=jboss,server=y,suspend=n&#8221;</p>
<p>транспорт может быть также dt_socket, флаг suspend означает то, будет ли перед запуском программа ждать подключения отладчика или запустится сразу. По указанному адресу (address) клиент JPDA будет подключаться к JBoss&#8217;у и в своей любимой IDE вы пропишете именно его. В данном случае адресом выступает строка &#8220;jboss&#8221;, однако, если вы используете сокетный транспорт, вам необходимо будет вместо имени указать порт.</p>
]]></content:encoded>
			<wfw:commentRss>http://elwood.su/?feed=rss2&amp;p=265</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL5InnoDBDialect и поля типа TEXT</title>
		<link>http://elwood.su/?p=260</link>
		<comments>http://elwood.su/?p=260#comments</comments>
		<pubDate>Sat, 05 Jun 2010 08:59:42 +0000</pubDate>
		<dc:creator>elwood</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://elwood.su/?p=260</guid>
		<description><![CDATA[Обнаружил сегодня очередной косяк в Hibernate, когда делал NativeQuery для таблицы, в которой имеется поле типа TEXT. Как известно, хибер по умолчанию не создает такие поля, а создает VARCHAR(255) для строковых значений, и тип TEXT я задал специально при создании Entity-бинов с использованием аннотации @Column(columnDefinition = &#8220;text&#8221;). И вот теперь select через NativeQuery не работает, [...]]]></description>
			<content:encoded><![CDATA[<p>Обнаружил сегодня очередной косяк в Hibernate, когда делал NativeQuery для таблицы, в<br />
которой имеется поле типа TEXT. Как известно, хибер по умолчанию не создает такие поля,<br />
а создает VARCHAR(255) для строковых значений, и<br />
тип TEXT я задал специально при создании Entity-бинов с использованием аннотации<br />
@Column(columnDefinition = &#8220;text&#8221;). И вот теперь select через NativeQuery не работает,<br />
потому что</p>
<p><code>MySQL5: No Dialect mapping for JDBC type: -1</code></p>
<p>Из обсуждений <a href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-1483">http://opensource.atlassian.com/projects/hibernate/browse/HHH-1483</a><br />
выяснилось, что этот диалект почему-то не хочет поддерживать тип TEXT.</p>
<p>В результате выяснилось, что победить эту проблему можно тремя способами :<br />
1. Отказаться от использования TEXT в пользу VARCHAR(65535) &#8211; но это не всегда возможно,<br />
особенно если база уже работает, и при выполнении alter table часть данных будет обрезана.<br />
2. Заюзать хибернейтовский метод addScalar при формировании запроса.<br />
<a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html">http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html</a> (16.1.1 Scalar queries)<br />
К сожалению, этот метод также не является идеальным, поскольку при использовании<br />
EJB3 (а я использую именно его) не представляется возможным лезть на уровень ниже и<br />
кастить интерфейс Query к хибернейтовскому SQLQuery, тем самым завязываясь на текущей<br />
хибернейтовской имплементации EJB3.<br />
3. Пропатчить класс-диалект, подменив его своим или занаследовавшись от него и добавив<br />
специальный кейс для типа TEXT. В данном случае все прошло великолепно, я закинул<br />
класс</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MySQL5InnoDBDialectPatched <span style="color: #000000; font-weight: bold;">extends</span> org.<span style="color: #006633;">hibernate</span>.<span style="color: #006633;">dialect</span>.<span style="color: #006633;">MySQL5InnoDBDialect</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> MySQL5InnoDBDialectPatched<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// register additional hibernate types for default use in scalar sqlquery type auto detection</span>
        registerHibernateType<span style="color: #009900;">&#40;</span><span style="color: #003399;">Types</span>.<span style="color: #006633;">LONGVARCHAR</span>, org.<span style="color: #006633;">hibernate</span>.<span style="color: #006633;">Hibernate</span>.<span style="color: #006633;">TEXT</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>в свойства persistence.xml, и все заработало.<br />
Единственное, что пришлось добавить в проект &#8211; compile-time-зависимости для сборки<br />
ejb-джарника. В моем случае это был всего лишь 1 файл hibernate3.jar.</p>
]]></content:encoded>
			<wfw:commentRss>http://elwood.su/?feed=rss2&amp;p=260</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Кодировка в multipart/form-data</title>
		<link>http://elwood.su/?p=257</link>
		<comments>http://elwood.su/?p=257#comments</comments>
		<pubDate>Sat, 01 May 2010 16:58:26 +0000</pubDate>
		<dc:creator>elwood</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://elwood.su/?p=257</guid>
		<description><![CDATA[При использовании commons.fileupload возникла проблема : русский текст, вводимый в input&#8217;ы, приходил в непонятной кодировке. Пробовал повесить фильтр, в котором выставить request&#8217;у и response&#8217;у кодировку utf-8 принудительно, но не помогло. Пробовал установить accept-charset на форме, тоже не помогло. Единственное найденное решение &#8211; у получаемых значений конвертить кодировку из iso-8859-1 в utf-8 : String convertedString = [...]]]></description>
			<content:encoded><![CDATA[<p>При использовании commons.fileupload возникла проблема : русский текст, вводимый в input&#8217;ы, приходил в непонятной кодировке. Пробовал повесить фильтр, в котором выставить request&#8217;у и response&#8217;у кодировку utf-8 принудительно, но не помогло. Пробовал установить accept-charset на форме, тоже не помогло.<br />
Единственное найденное решение &#8211; у получаемых значений конвертить кодировку из iso-8859-1 в utf-8 :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #003399;">String</span> convertedString <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span> <span style="color: #009900;">&#40;</span>string.<span style="color: #006633;">getBytes</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;iso-8859-1&quot;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;UTF-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Вроде работает. Надеюсь в будущем покопать глубже, а пока останется такой миникостыль.</p>
]]></content:encoded>
			<wfw:commentRss>http://elwood.su/?feed=rss2&amp;p=257</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IDEA IML-file import tip</title>
		<link>http://elwood.su/?p=252</link>
		<comments>http://elwood.su/?p=252#comments</comments>
		<pubDate>Sat, 01 May 2010 09:57:33 +0000</pubDate>
		<dc:creator>elwood</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://elwood.su/?p=252</guid>
		<description><![CDATA[Если у вас при импорте модуля (iml-файл) идея тупит (не подцепляются исходники, зависимости), не спешите нажимать Synchronize. Откройте iml-файл в текстовом редакторе и внимательно пройдитесь по его содержимому. Возможно, IDEA просто не нашла один из путей. В моем случае это был путь к части исходников, которые генерировались из WSDL в директорию build/src. На момент импорта [...]]]></description>
			<content:encoded><![CDATA[<p>Если у вас при импорте модуля (iml-файл) идея тупит (не подцепляются исходники, зависимости), не спешите нажимать Synchronize. Откройте iml-файл в текстовом редакторе и внимательно пройдитесь по его содержимому. Возможно, IDEA просто не нашла один из путей. В моем случае это был путь к части исходников, которые генерировались из WSDL в директорию build/src. На момент импорта модуля этих директорий не было (поскольку они создаются при билде модуля), и IDEA некорректно обработала эту ситуацию, проигнорировав прописанные в iml зависимости. После создания директорий build и build/src повторный импорт сработал на ура.<br />
В такой ситуации нажатие Synchronize приведет к тому, что IDEA перезапишет iml-файл, по сути, с нуля. Соответственно, потом файл будет закоммичен вами в VCS. В результате это может обернуться головной болью для всех других разработчиков, имеющих дело с модулем.</p>
]]></content:encoded>
			<wfw:commentRss>http://elwood.su/?feed=rss2&amp;p=252</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NBox и проблема с App.config</title>
		<link>http://elwood.su/?p=246</link>
		<comments>http://elwood.su/?p=246#comments</comments>
		<pubDate>Wed, 03 Mar 2010 13:47:56 +0000</pubDate>
		<dc:creator>elwood</dc:creator>
				<category><![CDATA[.NET]]></category>

		<guid isPermaLink="false">http://elwood.su/?p=246</guid>
		<description><![CDATA[Как известно, CLR при запуске .NET-приложения пытается прочитать config-файл с именем запускаемой сборки + расширение &#8220;.config&#8221;. Но ведь если запускаемый exe-файл переименовать, то config-файл не подгрузится &#8211; и приложение, возможно, перестанет работать. С этим частенько сталкиваются разработчики при работе над деплоингом приложения. И, к сожалению, .NET не содержит способов, позволяющих самому приложению задать имя config-файла [...]]]></description>
			<content:encoded><![CDATA[<p>Как известно, CLR при запуске .NET-приложения пытается прочитать config-файл с именем запускаемой сборки + расширение &#8220;.config&#8221;. Но ведь если запускаемый exe-файл переименовать, то config-файл не подгрузится &#8211; и приложение, возможно, перестанет работать. С этим частенько сталкиваются разработчики при работе над деплоингом приложения. И, к сожалению, .NET не содержит способов, позволяющих самому приложению задать имя config-файла во время некой процедуры &#8220;прединициализации&#8221;. Это возможно лишь для опций, которые читаются классом Settings путем написания собственного SettingsProvider&#8217;a, реализующего интерфейс IApplicationSettingsProvider (см <a href="http://msdn.microsoft.com/en-us/library/8eyb2ct1.aspx">Application Settings Architecture</a> для более подробной информации).</p>
<p>Но мы можем сделать самостоятельно из нашего приложения некий &#8220;микрозагрузчик&#8221;, который создает AppDomain, конфигурирует его и запускает сам себя, используя сконфигурированный AppDomain. Это действительно работает, причем в самом примитивном случае код очень компактен :</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">&nbsp;
 AppDomainSetup setupInfo <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> AppDomainSetup<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
 <span style="color: #FF0000;">string</span> entryAssemblyPath <span style="color: #008000;">=</span> Assembly.<span style="color: #0000FF;">GetEntryAssembly</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Location</span><span style="color: #008000;">;</span>
 <span style="color: #FF0000;">string</span> entryAssemblyDir <span style="color: #008000;">=</span> Path.<span style="color: #0000FF;">GetDirectoryName</span><span style="color: #000000;">&#40;</span>entryAssemblyPath<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
 setupInfo.<span style="color: #0000FF;">ApplicationBase</span> <span style="color: #008000;">=</span> Path.<span style="color: #0000FF;">GetDirectoryName</span><span style="color: #000000;">&#40;</span>entryAssemblyPath<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
 setupInfo.<span style="color: #0000FF;">ConfigurationFile</span> <span style="color: #008000;">=</span> Path.<span style="color: #0000FF;">Combine</span><span style="color: #000000;">&#40;</span>entryAssemblyDir, <span style="color: #666666;">&quot;MyApp.exe.config&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
 AppDomain forkedDomain <span style="color: #008000;">=</span> AppDomain.<span style="color: #0000FF;">CreateDomain</span><span style="color: #000000;">&#40;</span>Guid.<span style="color: #0000FF;">NewGuid</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>, <span style="color: #0600FF;">null</span>, setupInfo<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
 forkedDomain.<span style="color: #0000FF;">ExecuteAssembly</span><span style="color: #000000;">&#40;</span>Assembly.<span style="color: #0000FF;">GetEntryAssembly</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Location</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
 AppDomain.<span style="color: #0000FF;">Unload</span><span style="color: #000000;">&#40;</span>forkedDomain<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>Однако, необходимо следить за тем, чтобы такие ухищрения не приводили к сильной деградации производительности на этапе загрузки. Возможно, стоит написать отдельную сборку, которая будет загружать уже то, что нужно нам. Эта сборка будет очень малого размера, и работать будет практически без потери производительности.</p>
<p>А теперь подумаем, что произойдет, если у приложения, обработанного с помощью NBox (а это, как правило, один-единственный исполняемый файл), изменить имя файла. Если приложение не использовало config-файлы, то все будет ок. Но в противном случае &#8211; при запуске &#8211; CLR просто не подцепит старый конфиг, и приложение, скорее всего, работать не будет. Но, используя вышеприведенные приемы, мы можем заставить NBox распознать config-файл, и перезапустить самого себя, предварительно сконфигурировав AppDomain нужным config-файлом. А чтобы работа по разворачиванию файлов и сборок не производилась дважды, NBox может извлечь файлы во время начального запуска, и, перезапустившись, уже не извлекать файлы, работая со сборками. Таким образом можно минимизировать потери производительности, одновременно получая еще одну степень свободы в том, как сконфигурировать запускаемое приложение.</p>
<p>В принципе, теперь даже не обязательно извлекать config-файл рядом с exe-файлом упакованного приложения. NBox может закешировать извлекаемые config-файлы во временной директории, извлекая их заново в случае необходимости. Для пользователя это означает минус один файл, создаваемый в каталоге приложения, а для разработчика &#8211; уверенность в том, что его конфигурация будет применена независимо от названия exe-файла.</p>
<p>PS. Интересно, что метод AppDomainSetup.SetConfigurationBytes, который бы мог избавить нас от использования файлов в таких случаях, похоже, просто не работает <img src='http://elwood.su/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Здесь тред об этом : <a href="http://social.msdn.microsoft.com/Forums/en-US/clr/thread/5fa49361-85d0-4239-a557-621a29d0a087">AppDomainSetup.SetConfigurationBytes has no visible effect on configuration&#8230;</a></p>
]]></content:encoded>
			<wfw:commentRss>http://elwood.su/?feed=rss2&amp;p=246</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>О бомжах, деньгах и мотивации</title>
		<link>http://elwood.su/?p=237</link>
		<comments>http://elwood.su/?p=237#comments</comments>
		<pubDate>Sun, 03 Jan 2010 16:49:48 +0000</pubDate>
		<dc:creator>elwood</dc:creator>
				<category><![CDATA[Мысли вслух]]></category>

		<guid isPermaLink="false">http://elwood.su/?p=237</guid>
		<description><![CDATA[Как известно, за последние несколько лет в интернетах появилось и разрослось движение Интернет бомжей. Основная идея сферического бомжа в вакууме заключается в том, чтобы заработать побольше денег &#8220;в интернете&#8221;, не работая &#8220;на дядю&#8221; в реале. Заработок, к которому стремится среднестатистический бомж &#8211; так называемый &#8220;пассивный&#8221;, т.е. один раз сделал какую-то сеть сайтов, продал ссылки, разместил [...]]]></description>
			<content:encoded><![CDATA[<p>Как известно, за последние несколько лет в интернетах появилось и разрослось движение Интернет бомжей. Основная идея сферического бомжа в вакууме заключается в том, чтобы заработать побольше денег &#8220;в интернете&#8221;, не работая &#8220;на дядю&#8221; в реале. Заработок, к которому стремится среднестатистический бомж &#8211; так называемый &#8220;пассивный&#8221;, т.е. один раз сделал какую-то сеть сайтов, продал ссылки, разместил рекламку &#8211; и сиди, кури сигару, в раздумьях, как бы еще срубить бабла, ну или делай следующую партию сайтов в то время как денежки капают. У каждого не обремененного огромными доходами человека, который заходит почитать бомжеблоги успешных бомжей, возникает естественная мысль &#8211; почему бы тоже не попробовать ?<br />
У меня двойственное отношение к этим бомжам. С одной стороны, это конечно круто &#8211; иметь собственный доход, не зависеть от начальства в реале, не платить налоги, постоянно развиваться итд итп. Но с другой стороны &#8211; какова цель всего этого ? Деньги. И люди тратят годы на то, чтобы сделать (уточню &#8211; не заработать, а сделать) деньги с помощью сомнительных средств (как то &#8211; наебалово доверчивых пользователей (к примеру, через смс), наебалово поисковых машин). Ну добыл денег &#8211; что дальше ? Прожигать жизнь или детям рассказывать, как юзеров-лохов на смсках разводил ? Ладно, опустим моральный аспект. Допустим, бомж работал несколько лет таким способом, и опыт у него &#8211; исключительно в поднятии денежных средств. А если этим заниматься не интересно ? Ну вот нравится если рыбу ловить &#8211; что, всю жизнь тратить на SEO ? Или мне, например, нравится программирование, музыка, и все, что с этим связано &#8211; мне совершенно неинтересно клепать сайты и искать способы подороже их втулить. Вопрос &#8211; как найти интересующую область деятельности, не &#8220;работая на дядю&#8221; и с приличным доходом ? Недавно видел на хабре пару постов от так называемых независимых разработчиков. Но &#8211; так ли они независимы на самом деле ? У обоих весь доход &#8211; от флеш игрушек. Интересно, им не надоело еще эти игрушки клепать ?<br />
То же самое относится и к фрилансу &#8211; фрилансер волен лишь выбирать заказчика, но продукт и то, каким он будет &#8211; не в его власти.<br />
В общем, крутость бомжевания, фрилансирования и независиморазрабатывания лишь поверхностна. А то, кем быть и как трудиться &#8211; дело выбора каждого, в зависимости от личных предпочтений и поставленных целей. И вопрос &#8211; как заработать приличные деньги, приобрести ценный опыт и пассивный доход, работая в интересующей области &#8211; по-прежнему остается открытым.</p>
]]></content:encoded>
			<wfw:commentRss>http://elwood.su/?feed=rss2&amp;p=237</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>minifmod4net</title>
		<link>http://elwood.su/?p=233</link>
		<comments>http://elwood.su/?p=233#comments</comments>
		<pubDate>Fri, 01 Jan 2010 23:57:46 +0000</pubDate>
		<dc:creator>elwood</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[С/C++]]></category>

		<guid isPermaLink="false">http://elwood.su/?p=233</guid>
		<description><![CDATA[Не так давно мутил я на дотнете воспроизведение трекерных файлов, а именно, XM. Громоздкие либы типа BASS явно для этой задачи не подходили, широко известный в узких кругах ufmod почему-то в связке с дотнет интеропом не заработал, зато нашлась библиотечка minifmod, которая обладала всеми необходимыми качествами (интересовала возможность загрузки из файла и из памяти) и [...]]]></description>
			<content:encoded><![CDATA[<p>Не так давно мутил я на дотнете воспроизведение трекерных файлов, а именно, <a href="http://en.wikipedia.org/wiki/XM_(file_format)">XM</a>. Громоздкие либы типа <a href="http://www.un4seen.com/">BASS</a> явно для этой задачи не подходили, широко известный в узких кругах <a href="ufmod.sourceforge.net">ufmod</a> почему-то в связке с дотнет интеропом не заработал, зато нашлась библиотечка <a href="http://www.fmod.org/index.php/download">minifmod</a>, которая обладала всеми необходимыми качествами (интересовала возможность загрузки из файла и из памяти) и небольшими габаритами. Для того, чтобы можно было удобно указывать способ загрузки (из файла или из памяти), я дописал маленький адаптер, который обрабатывал callback&#8217;и минифмода, и засунул его в DLL. Соответственно, нативная DLL к .net-проекту была подцеплена через простейший interop.</p>
<p>Сегодня наконец собрался с мыслями, почистил файлы проекта, и выложил все на гуглокод, благо sourceforge и codeplex уже попробовал. Google code очень понравился своей беспроблемностью в залитии файлов и работе с SVN. Вспоминая, как я трахался с sourceforge через SFTP чтобы залить туда пару архивов, могу сказать, что здесь все очень и очень удобно.</p>
<p>Итак, сайт проекта находится здесь <a href="http://code.google.com/p/minifmod4net/">http://code.google.com/p/minifmod4net/</a></p>
<p>Код использования библиотеки прост как пять копеек, достаточно взглянуть на тестовый пример, чтобы все стало ясно. Только один момент &#8211; если вы желаете использовать ее в своей программе, то вам придется сменить режим генерации кода с AnyCPU на x86, поскольку имеется нативная DLL с 32-битным кодом, и в режиме AnyCPU на какой-нибудь 64-битной винде программа не запустится, мотивировав отказ исключением наподобие ImageBadFormatException. Если же х86 специфицировать явно, то все будет работать и на 64-битных Windows.</p>
<p>PS. Поздравляю всех с наступившим 2010 годом, надеюсь, он принесет всем нам немало радости и профессиональных успехов <img src='http://elwood.su/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://elwood.su/?feed=rss2&amp;p=233</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Идея насчет синтаксиса обработки исключений</title>
		<link>http://elwood.su/?p=216</link>
		<comments>http://elwood.su/?p=216#comments</comments>
		<pubDate>Thu, 24 Dec 2009 21:23:18 +0000</pubDate>
		<dc:creator>elwood</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Мысли вслух]]></category>
		<category><![CDATA[С/C++]]></category>

		<guid isPermaLink="false">http://elwood.su/?p=216</guid>
		<description><![CDATA[Часто приходится писать обработчики исключений, которые делают одно и то же. Например, в следующем кусочке кода нам необходимо среагировать на исключения типа Exception1 и Exception2 записью в лог-файл : try &#123; // Блок, который может вызвать исключения Exception1, Exception2 // или исключение любого другого типа &#125; catch &#40;Exception1 exc&#41; &#123; logger.WarnException&#40;&#34;An exception has been occured [...]]]></description>
			<content:encoded><![CDATA[<p>Часто приходится писать обработчики исключений, которые делают одно и то же. Например, в следующем кусочке кода нам необходимо среагировать на исключения типа Exception1 и Exception2 записью в лог-файл :</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">try</span> <span style="color: #000000;">&#123;</span>
  <span style="color: #008080; font-style: italic;">// Блок, который может вызвать исключения Exception1, Exception2</span>
  <span style="color: #008080; font-style: italic;">// или исключение любого другого типа</span>
<span style="color: #000000;">&#125;</span> <span style="color: #0600FF;">catch</span> <span style="color: #000000;">&#40;</span>Exception1 exc<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  logger.<span style="color: #0000FF;">WarnException</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;An exception has been occured : {0}&quot;</span>, exc<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span> <span style="color: #0600FF;">catch</span> <span style="color: #000000;">&#40;</span>Exception2 exc<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  logger.<span style="color: #0000FF;">WarnException</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;An exception has been occured : {0}&quot;</span>, exc<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Проблема в том, что мы не можем никак избежать дублирования кода. Единственный выход &#8211; создать отдельный метод-обработчик, в котором и инкапсулировать логику. Но &#8211; во-первых, это может оказаться неудобным, поскольку локальные переменные, которые могут понадобиться в обработчике, придется передавать при вызове функции, а во-вторых, сам по себе вызов функции &#8211; это еще несколько тактов процессора.<br />
Хотелось бы иметь способ, который бы позволял писать, скажем, следующим образом :</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">try</span> <span style="color: #000000;">&#123;</span>
  <span style="color: #008080; font-style: italic;">// </span>
<span style="color: #000000;">&#125;</span> <span style="color: #0600FF;">catch</span> <span style="color: #000000;">&#40;</span>Exception1, Exception2 exc <span style="color: #0600FF;">as</span> Exception<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  <span style="color: #008080; font-style: italic;">// exc имеет тип Exception</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p><span id="more-216"></span></p>
<p>(Предполагается, что типы Exception1 и Exception2 занаследованы от базового класса Exception).<br />
Этот код мог бы преобразовываться в следующий :</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">&nbsp;
Exception exc <span style="color: #008000;">=</span> null<span style="color: #008000;">;</span>
<span style="color: #0600FF;">try</span> <span style="color: #000000;">&#123;</span>
  <span style="color: #008080; font-style: italic;">// </span>
<span style="color: #000000;">&#125;</span> <span style="color: #0600FF;">catch</span> <span style="color: #000000;">&#40;</span>Exception1 exc1<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  exc <span style="color: #008000;">=</span> exc1<span style="color: #008000;">;</span>
  <span style="color: #0600FF;">goto</span> exception_real_handler<span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span> <span style="color: #0600FF;">catch</span> <span style="color: #000000;">&#40;</span>Exception2 exc2<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
  exc <span style="color: #008000;">=</span> exc2<span style="color: #008000;">;</span>
  <span style="color: #0600FF;">goto</span> exception_real_handler<span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
exception_real_handler<span style="color: #008000;">:</span>
<span style="color: #008080; font-style: italic;">// Работаем с exc как с базовым типом Exception.</span></pre></div></div>

<p>На мой взгляд, это было бы не сложно реализуемым дополнительным синтаксическим сахаром. Вполне применимо к c#, java и C++. Хотя, на счет последнего сомневаюсь, поскольку в С++ на поверку все оказывается несколько сложнее, чем изначально предполагаешь <img src='http://elwood.su/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Единственное &#8211; это необходимо продумать, каким образом компилятор должен реагировать на конструкции вида catch (Exception1, Exception2 exc as Exception) в случае, если Exception1 занаследован от Exception2. Мне видятся несколько путей, по которым мог бы пойти компилятор.</p>
<ul>
<li>Выдавать ошибку при компиляции.<br />
   Самый жесткий поход. На мой взгляд, это излишне.</li>
<li>Игнорировать наличие более конкретных типов.<br />
  Т.е. если идет строчка catch (Exception1, Exception2 exc as Exception), в которой Exception1 : Exception2, то она будет интерпретирована как простой catch (Exception2). Вполне понятный подход.</li>
<li>Игнорировать и выдавать предупреждение &#8211; наверное, самый правильный способ.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://elwood.su/?feed=rss2&amp;p=216</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Проблема с преобразованием к самому себе в GCC</title>
		<link>http://elwood.su/?p=205</link>
		<comments>http://elwood.su/?p=205#comments</comments>
		<pubDate>Sun, 20 Dec 2009 21:58:13 +0000</pubDate>
		<dc:creator>elwood</dc:creator>
				<category><![CDATA[Linux/Unix]]></category>
		<category><![CDATA[С/C++]]></category>

		<guid isPermaLink="false">http://elwood.su/?p=205</guid>
		<description><![CDATA[Не так давно я прикрутил фичу, описанную в предыдущем посте, к своим умным указателям, и вот недавно счастье было разрушено падением программы. Проблема была локализована в следующем коде : const HandlePointer&#60;lib3dsfile&#62;&#38; file = loadFile&#40;&#41;; Функция loadFile() возвращала HandlePointer&#60;Lib3dsFile&#62; по значению, и по идее это значение должно было быть привязано (bind) к константной ссылке. Время жизни [...]]]></description>
			<content:encoded><![CDATA[<p>Не так давно я прикрутил фичу, описанную в предыдущем посте, к своим умным указателям, и вот недавно счастье было разрушено падением программы. Проблема была локализована в следующем коде :</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">const</span> HandlePointer<span style="color: #000080;">&lt;</span>lib3dsfile<span style="color: #000080;">&gt;</span><span style="color: #000040;">&amp;</span> file <span style="color: #000080;">=</span> loadFile<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>Функция loadFile() возвращала HandlePointer&lt;Lib3dsFile&gt; по значению, и по идее это значение должно было быть привязано (bind) к константной ссылке. Время жизни временного (temporary) объекта в этом случае по Стандарту должно быть продлено и временный объект должен быть жив до тех пор, пока жива константная ссылка. Однако, добавив диагностических логов, я с удивлением отметил, что деструктор временного объекта в данном случае вызывается сразу после выполнения этой строки, не дожидаясь выхода ссылки из области видимости. Замена ссылки на объект-копию магическим образом исцеляло программу, временный объект уничтожался после вызова конструктора копий, и программа работала как раньше.</p>
<p>Добавив еще чуть больше логов, я удивился еще раз, увидев, что в указанном выражении вызывается<br />
оператор преобразования HandlePointer&lt;T&gt;::operator T&#038; () , то есть объект преобразовывался к самому себе, однако при этом объект уже не привязывался к константной ссылке, а уничтожался автоматически после вычисления полного выражения (full expression).</p>
<p>Дома для проверки написал тестовую программу, которая объявляла класс Test и оператор преобразования к типам Test&#038; и const Test&#038; :</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> Test
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
	Test<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Default constructor<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
	~Test<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>	<span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Destructor<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>	<span style="color: #008000;">&#125;</span>
	Test<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> Test<span style="color: #000040;">&amp;</span> copy<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Copy constructor<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
	Test<span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> Test<span style="color: #000040;">&amp;</span> copy<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		<span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;operator =<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">return</span> <span style="color: #000040;">*</span><span style="color: #0000dd;">this</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #666666;">//</span>
	operator Test<span style="color: #000040;">&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
		<span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;operator Test&amp;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">return</span> <span style="color: #000040;">*</span><span style="color: #0000dd;">this</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	operator <span style="color: #0000ff;">const</span> Test<span style="color: #000040;">&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span> <span style="color: #008000;">&#123;</span>
		<span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;operator const Test&amp;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">return</span> <span style="color: #000040;">*</span><span style="color: #0000dd;">this</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
Test someFunc<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">return</span> Test<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #008000;">&#123;</span>
		<span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Begin<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">const</span> Test<span style="color: #000040;">&amp;</span> test <span style="color: #000080;">=</span> someFunc<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;End<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Натравив на него компиляторы Visual C++ и GCC, посмотрел на результаты. Произошло все так же, как и в случае шаблонных классов :</p>
<p>Вывод программы, скомпилированной Visual C++ :<br />
<code>Begin<br />
Default constructor<br />
<strong>End<br />
Destructor</strong></code></p>
<p>Вывод программы, скомпилированной GCC :<br />
<code>Begin<br />
Default constructor<br />
operator Test&#038;<br />
Copy constructor<br />
Destructor<br />
operator Test&#038;<br />
<strong>Destructor<br />
End</strong></code></p>
<p>На обилие конструкторов копий и деструкторов в выводе GCC можно не обращать внимания &#8211; это<br />
всего лишь говорит о том, что GCC не выполнил здесь RVO (Return Values Optimization). Главное -<br />
что в Visual C++ временный объект живет до конца блока { }, а в GCC уничтожается сразу.</p>
<p>Почему поведение GCC здесь мне представляется неверным ? Допустим, у вас есть класс. У класса есть<br />
дефолтные операторы преобразования их к ссылке и к константной ссылке, генерируемые компилятором автоматически. И временные объекты успешно привязываются к константным ссылкам, продлевая их время жизни. Однако, если вы вдруг (как сейчас я) захотите написать свою версию такого оператора (что в принципе, бессмысленно, но в контексте использования шаблонов смысл приобретает), то вы уже не сможете действовать по старым правилам. Таким образом, явное определение пользовательского оператора преобразования (такого же, как и дефолтный, по сути) изменяет поведение объектов и семантику в целом.</p>
<p>В общем, сбило порядочно меня все это с толку, и я обратился за помощью на блог <a href="http://alenacpp.blogspot.com/2008/01/const.html#comment-7732964570204317744">Алены С++</a> (в котором как раз недавно читал про RVO и привязку временных объектов к const&#038; ) и на <a href="http://rsdn.ru/forum/cpp/3646363.1.aspx">RSDN</a>.<br />
На следующий день поступили комментарии, позволяющие разобраться в том, что же все-таки происходит и какой из компиляторов в данном случае прав.</p>
<p><strong>Краткое резюме беседы (для тех, кому лениво читать обсуждение) :</strong></p>
<p>Здесь мы видим следствие изначального внутреннего противоречия в Стандарте 98 (см ветку на RSDN).<br />
Стандарт был скорректирован в дальнейшем в ходе внесения правок и уточнений.<br />
На данный момент корректным поведением является поведение, при котором компилятор не должен вызвать переопределенные операторы преобразования в случае, если это преобразование выполняется к ссылке на тот же тип или к объекту того же типа:</p>
<blockquote><p>12.3.2/1<br />
&#8230;<br />
A conversion function is never used to convert a (possibly cv-qualified)<br />
object to the (possibly cv-qualified) same object type (or a reference to it)</p></blockquote>
<p>Таким образом, компилятор GCC на данный момент не соответствует исправленному Стандарту.<br />
Что ж, печально, придется использовать вместо неявных преобразований явный вызов функции.<br />
Хотя, возможно, есть способ, который бы позволил ограничить шаблонный метод преобразования таким образом, чтобы он не использовался, когда тип T идентичен типу U ? Я попробовал пошаманить с<br />
шаблонами и SFINAE, но пока ничего путного не вышло. Если у кого-нибудь есть такое решение,<br />
было бы интересно о нем узнать.</p>
]]></content:encoded>
			<wfw:commentRss>http://elwood.su/?feed=rss2&amp;p=205</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
