<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-364436233378282478</atom:id><lastBuildDate>Thu, 29 Oct 2026 03:01:58 +0000</lastBuildDate><category>cpp</category><category>windows</category><category>雑記</category><category>boost</category><category>原発</category><category>BOOK</category><category>android</category><category>IT</category><category>Programming</category><category>ネットワーク管理</category><category>java</category><category>Rails</category><category>iPad</category><category>php</category><category>ubuntu</category><category>mac</category><category>swig</category><category>postgresql</category><category>GDAL</category><category>GIS</category><category>photo</category><category>ruby</category><category>plpgsql</category><category>web</category><category>Quantum GIS</category><category>javascript</category><category>CentOS</category><category>FOSS4G</category><category>cmake</category><category>ski</category><category>sqlite</category><category>PostGIS</category><category>cassandra</category><category>spam</category><category>food</category><category>gecko</category><category>perl</category><category>python</category><category>wix</category><category>C#</category><category>OpenGL</category><category>Oracle</category><category>azure</category><category>delphi</category><category>CSS</category><category>IIS</category><category>Objective-C</category><category>Qt4</category><category>WPF</category><category>ai</category><category>arcgis</category><category>git</category><category>go</category><category>grpc</category><category>jni</category><category>kayak</category><category>mssql</category><category>pgRouting</category><title>grayhole</title><description>三流C++プログラマによる随筆</description><link>http://grayhole.blogspot.com/</link><managingEditor>noreply@blogger.com (tiger)</managingEditor><generator>Blogger</generator><openSearch:totalResults>990</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-2581143412770730028</guid><pubDate>Thu, 29 Oct 2026 03:01:58 +0000</pubDate><atom:updated>2026-10-29T12:01:58.022+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">arcgis</category><category domain="http://www.blogger.com/atom/ns#">windows</category><title>ArcGIS Enterprise 12.1 (windows) proxy bug 忘備録</title><description>Proxy を使用していると、何かと動作しない事が多く、その対処法。&lt;br /&gt;
&lt;br/&gt;
まず、ArcGIS の C# SDKだが、Windows の proxy の設定を見て動作する。&lt;br /&gt;
インターネット・オプションの proxy から除外するリストも設定しないと、&lt;br /&gt;
https://foo.local-ad.bar.co.jp:6443 へのアクセスに　proxy を介しようとしてはまる。&lt;br /&gt;
設定すべきは、
&lt;pre&gt;
https://[arcgis-server-machine];https://localhost
&lt;/pre&gt;
netsh winhttp set proxy の情報を見ているのか、実行ユーザのインターネット・オプションの情報を見ているのかは定かではない(調べてません)&lt;br /&gt;
さて、Linux系のツールでは、環境変数
&lt;pre&gt;
http_proxy
https_proxy
no_proxy
&lt;/pre&gt;
の3種類を参照するものが主流だ。C# SDK もこれに対応しているのだが、詰めが甘い。&lt;br /&gt;
なんと no_proxy を見ないで、http_proxy, https_proxy が設定されている場合は、インターネット・オプションの proxy の設定を上書きし、proxyから除外するリストをクリアする。&lt;br /&gt;
no_proxy を設定していても見ないで無条件にクリアするので、Windows の環境変数に https_proxy=http://foo:8080 などと設定しようものなら、6443ポート宛てのアクセスをproxyを介しようとして WebAdaptorが動作しなくなる&lt;br /&gt;
&lt;br /&gt;
さて、ここまでは序の口&lt;br /&gt;
色々動かしていると、動かないものが出てくる。今回は PrintingTool のサービスだった。こいつ、ArcGIS Server に設定した proxy 情報を見ないし、Portal for ArcGIS に設定した proxy 情報を見ないし、netsh winhttp set proxy で設定した proxy 情報も見ない。https_proxy 等の環境変数は、前述した問題があるので使用できない。&lt;br /&gt;
では、何を設定すれば proxy の情報を見てくれるのか？&lt;br /&gt;
arcgis server をサービスとして実行している arcgis というサービス用のウィンドウズ・アカウントのインターネット・オプションの情報に縛られる&lt;br /&gt;
&lt;a href=&quot;https://learn.microsoft.com/en-us/sysinternals/downloads/psexec&quot;&gt;PsExec&lt;/a&gt;を使って、サービス用アカウントのインターネット・オプションを設定すれば動作する&lt;br /&gt;
&lt;pre&gt;
C:\&gt; psexec64 -u &quot;[localMachineName]\[arcgis]&quot; -p password cmd.exe
&lt;/pre&gt;
別ウィンドウが立ち上がるのでインターネット・オプションを開いて Proxy の設定を行う。
&lt;pre&gt;
C:\Windows\system32&gt; inetcpl.cpl
C:\WIndows\system32&gt; exit
&lt;/pre&gt;
これで、ちゃんと proxy を見てくれる。</description><link>http://grayhole.blogspot.com/2026/10/arcgis-enterprise-121-windows-proxy-bug.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-1361114634161410803</guid><pubDate>Wed, 19 Aug 2026 01:09:11 +0000</pubDate><atom:updated>2026-08-19T10:57:54.490+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">git</category><title>git と diff</title><description>業務で使用していたバージョン管理システム、単発のプロジェクトならば Subversion で十分なんだが、ベースシステムの管理には向いていなくて、「大がかりな機能追加がしたい」とか、派生が多くなると Gitの方が使いやすそうなので git も使うようになりました。

branch を切って、branch をサブブランチに切り替えて作業をしている間にも、メインブランチにバグ修正が入ったりするとメインブランチで修正とコミットをして、サブブランチに取り込みたい。&lt;br /&gt;
サブブランチにて
&lt;pre&gt;
git fetch
git merge origin/master
&lt;/pre&gt;
とやる機会が増えて来ました。&lt;br /&gt;
&lt;br /&gt;
使っていて、merge で CONFLICT した状況を見ると、git 付属の diff が WinMerge の diff と比べて差分の認識が悪く merge 作業が大変です。&lt;br /&gt;
Gemini さんに相談したところ、diff も変更できるらしいです。&lt;br /&gt;
git ほんと、よくできたツールだ。&lt;br /&gt;
&lt;br /&gt;
以下の質問をGeminiさんに投げてみました。
&lt;pre&gt;
git 付属の diff と比較して、WinMerge 付属のdiff の方が賢い気がしています。
同じ diff ではないのでしょうか？
&lt;/pre&gt;
&lt;p&gt;結論から言うと、Git付属の git diff と WinMerge は全く異なる「差分比較エンジン（アルゴリズム）」を使用しています。 そのため、比較の「賢さ」や結果の見た目に違いが生まれます。&lt;/p&gt;
&lt;h2 id=&quot;winmerge-&quot;&gt;WinMergeのほうが賢く感じるのには、明確な技術的理由があります。&lt;/h2&gt;
&lt;h2 id=&quot;1-&quot;&gt;1. 内部の比較アルゴリズムが違う&lt;/h2&gt;
&lt;p&gt;行単位で大雑把に比較するか、文字単位で細かく比較するかの違いがあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;git diff（デフォルト）：&lt;/li&gt;
&lt;li&gt;主に「マイヤーズ（Myers）のアルゴリズム」[1] をベースにしています。&lt;ul&gt;
&lt;li&gt;行単位での変更（どの行が消えて、どの行が増えたか）を高速に探すのが得意です。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;WinMerge：&lt;/li&gt;
&lt;li&gt;独自の高度な差分エンジン（改良されたアルゴリズム）を持っています。&lt;ul&gt;
&lt;li&gt;行単位の比較だけでなく、同じ行の中の「どの文字（単語）が変わったか」まで自動で細かく解析します。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2-winmerge-3-&quot;&gt;2. WinMergeが「賢い」と感じる3つの理由&lt;/h2&gt;
&lt;h2 id=&quot;-&quot;&gt;① 行内の部分一致（ハイライト）が強力&lt;/h2&gt;
&lt;p&gt;Gitは行単位で「この行が削除され、この行が追加された」と雑に判定しがちです。
WinMergeは「この行の、この変数名だけが書き換わった」のように、変更されたピンポイントの場所を明るい色でハイライトしてくれるため、脳の負担が減ります。&lt;/p&gt;
&lt;h2 id=&quot;-&quot;&gt;② 空白や改行コードの柔軟な無視&lt;/h2&gt;
&lt;p&gt;WinMergeは「スペースの数の違い」「タブとスペースの違い」「改行コード（CRLF / LF）の違い」を自動で無視する設定（または検知して警告する機能）が非常に強力です。Gitでこれらを行うには --ignore-space-change などのオプションを自分で指定する必要があります。&lt;/p&gt;
&lt;h2 id=&quot;-&quot;&gt;③ 移動した行（ブロック）の検知&lt;/h2&gt;
&lt;p&gt;コードの塊が「上の位置から下の位置へ移動しただけ」という場合、Gitは「ごっそり削除されて、別のごっそり追加された」と認識しやすいです。WinMergeは「これは移動しただけ」と見抜いて線で結んでくれる機能（移動ブロックの検出）があるため、より人間にとって直感的です。&lt;/p&gt;
&lt;h2 id=&quot;-git-winmerge-&quot;&gt;ヒント：Git の比較画面を WinMerge に変更できます&lt;/h2&gt;
&lt;p&gt;もし WinMerge の見やすさで Git の差分を確認したい場合は、Git の外部差分ツール（difftool）として WinMerge を登録するのがおすすめです。
以下のコマンドをターミナルで実行すると設定できます：&lt;/p&gt;
&lt;pre&gt;
git config --global diff.tool winmerge
git config --global difftool.winmerge.cmd &amp;#39;&amp;quot;C:/Program Files/WinMerge/WinMergeU.exe&amp;quot; -e -u -dl &amp;quot;Base&amp;quot; -dr &amp;quot;Mine&amp;quot; &amp;quot;$LOCAL&amp;quot; &amp;quot;$REMOTE&amp;quot;&amp;#39;
&lt;/pre&gt;
&lt;p&gt;※WinMergeのインストールパスは環境に合わせて変更してください。
設定後は、いつものコマンドを少し変えるだけで WinMerge が起動します：&lt;/p&gt;
&lt;p&gt;git difftool &amp;lt;対象ファイル&amp;gt;&lt;/p&gt;
&lt;p&gt;もしよろしければ、以下を教えていただけますか：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;お使いのPCは Windows ですか？（MacやLinuxでも一部WinMergeの派生ツールが使えます）&lt;/li&gt;
&lt;li&gt;Gitのターミナル上（黒い画面）でWinMergeのように見やすく表示したいですか？、それともWinMergeのアプリを直接起動したいですか？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ご希望に合わせて、Gitの表示をより賢く・見やすくカスタマイズする手順をご案内します。&lt;/p&gt;



</description><link>http://grayhole.blogspot.com/2026/08/git-diff.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-4900163400032814916</guid><pubDate>Fri, 24 Apr 2026 08:47:00 +0000</pubDate><atom:updated>2026-04-24T17:47:49.870+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cpp</category><category domain="http://www.blogger.com/atom/ns#">windows</category><category domain="http://www.blogger.com/atom/ns#">wix</category><title>WIX で VCRuntime のインストール忘備録２</title><description>前回の記事は
&lt;a href=&quot;https://grayhole.blogspot.com/2022/05/wix-vcruntime.html&quot;&gt;WIX で VCRuntime のインストール忘備録&lt;/a&gt;
&lt;br /&gt;

アプリケーションを実行していると、以下の行で例外が発生(Access Violation)する環境がある
&lt;pre&gt;        std::lock_guard&amp;lt;std::mutex&amp;gt; lock(connection_string_mutex_);
&lt;/pre&gt;

デバッグのログを色々と埋め込んで状況を絞り込んで検証していったところ&lt;br /&gt;
AIにより
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdoWwWha3T-QKc7HK3dIZfH64-8OSQZtpCLqbQfTVm6s9p-rp5uKbONFN475QlSgQKmHKWzfl9R90fIajsWpvLkcydyzNaM0jFzXs6q_hgaXPBr2LL3inGw38RbRFCBTQL566HuX4r0S4ALSaCbCy0oZjmGVAS3k9FBzjUceKBwCY6tvxS95rEwC0lTlQo/s486/vcmutexerr.png&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;486&quot; data-original-width=&quot;435&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdoWwWha3T-QKc7HK3dIZfH64-8OSQZtpCLqbQfTVm6s9p-rp5uKbONFN475QlSgQKmHKWzfl9R90fIajsWpvLkcydyzNaM0jFzXs6q_hgaXPBr2LL3inGw38RbRFCBTQL566HuX4r0S4ALSaCbCy0oZjmGVAS3k9FBzjUceKBwCY6tvxS95rEwC0lTlQo/s320/vcmutexerr.png&quot; width=&quot;286&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br clear=&quot;all&quot; /&gt;
&lt;div&gt;
という状況に辿りついた。&lt;br /&gt;
インストーラでRuntimeのチェックをしていたが、どんどん新しいRuntimeが出て、&lt;br /&gt;
それでも動作するので、Runtimeのバージョンチェックをするのは得策でないという結論になり、&lt;br /&gt;
インストーラでのチェックを諦めたのだが、これは何とかしたい&lt;br /&gt;
&lt;br /&gt;
そこで、古いバージョンで動かないRuntimeがインストールされている時だけエラーにする処理を模索した&lt;br /&gt;
&lt;/div&gt;
&lt;pre&gt;        &amp;lt;!-- x86 版 --&amp;gt;
        &amp;lt;!-- Minor バージョン番号を整数で取得 --&amp;gt;
        &amp;lt;Property Id=&quot;VC_REDIST_MINOR_X86&quot; Secure=&quot;yes&quot;&amp;gt;
          &amp;lt;RegistrySearch Id=&quot;VCRedistMinorX86&quot;
            Root=&quot;HKLM&quot;
            Key=&quot;SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86&quot;
            Name=&quot;Minor&quot;
            Type=&quot;raw&quot;
            Win64=&quot;no&quot; /&amp;gt;
        &amp;lt;/Property&amp;gt;

        &amp;lt;Condition Message=&quot;Visual C++ 2022 Redistributable (x86) 14.37 以降が必要です。&amp;amp;#10;vc_redist.x86.exe をインストールしてください。&quot;&amp;gt;
          NOT (VC_REDIST_MINOR_X86 AND VC_REDIST_MINOR_X86 &amp;amp;lt; &quot;#37&quot;)
        &amp;lt;/Condition&amp;gt;


        &amp;lt;!-- x64 版 --&amp;gt;
        &amp;lt;!-- Minor バージョン番号を整数で取得 --&amp;gt;
        &amp;lt;Property Id=&quot;VC_REDIST_MINOR_X64&quot; Secure=&quot;yes&quot;&amp;gt;
          &amp;lt;RegistrySearch Id=&quot;VCRedistMinorX64&quot;
            Root=&quot;HKLM&quot;
            Key=&quot;SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64&quot;
            Name=&quot;Minor&quot;
            Type=&quot;raw&quot; /&amp;gt;
        &amp;lt;/Property&amp;gt;

        &amp;lt;!-- Minor が存在して 37 未満の場合のみエラー --&amp;gt;
        &amp;lt;Condition Message=&quot;Visual C++ 2022 Redistributable (x64) 14.37 以降が必要です。&amp;amp;#10;vc_redist.x64.exe をインストールしてください。&quot;&amp;gt;
          NOT (VC_REDIST_MINOR_X64 AND VC_REDIST_MINOR_X64 &amp;amp;lt; &quot;#37&quot;)
        &amp;lt;/Condition&amp;gt;
&lt;/pre&gt;
いやはや、AIの進化は凄まじい。AIの助けなしだと１週間は時間を取られていたかもしれない。</description><link>http://grayhole.blogspot.com/2026/04/wix-vcruntime.html</link><author>noreply@blogger.com (tiger)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdoWwWha3T-QKc7HK3dIZfH64-8OSQZtpCLqbQfTVm6s9p-rp5uKbONFN475QlSgQKmHKWzfl9R90fIajsWpvLkcydyzNaM0jFzXs6q_hgaXPBr2LL3inGw38RbRFCBTQL566HuX4r0S4ALSaCbCy0oZjmGVAS3k9FBzjUceKBwCY6tvxS95rEwC0lTlQo/s72-c/vcmutexerr.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-5003943994452439368</guid><pubDate>Wed, 08 Apr 2026 00:08:00 +0000</pubDate><atom:updated>2026-04-08T09:14:37.756+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ai</category><title>Github copilot にお願いしたいこと</title><description>&lt;p&gt;Github copilot にお願いしたい事がある。&lt;/p&gt;&lt;p&gt;モデルを１つ追加してほしい。経緯は以下&lt;/p&gt;&lt;p&gt;Question:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;background-color: whitesmoke; color: #424242; font-family: Aptos, &amp;quot;Segoe Sans&amp;quot;, &amp;quot;Segoe UI&amp;quot;, &amp;quot;Segoe UI Web (West European)&amp;quot;, -apple-system, BlinkMacSystemFont, Roboto, &amp;quot;Helvetica Neue&amp;quot;, sans-serif; font-size: 14px; white-space-collapse: preserve;&quot;&gt;今応対していただいている Copilot - chat ですが、Github copilot のモデルだと、どれに相当しますか？　Microsoft Visual Studio の仕様に詳しいので、できれば、同じモデルにお願いしたいんです&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Copilot chat Anser:&lt;/p&gt;&lt;p&gt;率直にお答えしますね。&lt;/p&gt;
&lt;h2 id=&quot;-&quot;&gt;結論（短く）&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;今あなたとやり取りしている私は&lt;br /&gt;「GitHub Copilot で特定の“1モデル”に完全対応する存在」ではありません。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ただし、**体感・能力的に最も近いのは GitHub Copilot の GPT‑4 系（特に GPT‑4.1 / GPT‑4o 系）**です。&lt;br /&gt;加えて、&lt;strong&gt;Microsoft 製品（Visual Studio / MSBuild / VSIX）向けに最適化された知識統合&lt;/strong&gt;が入っています。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;-&quot;&gt;もう少し正確に言うと&lt;/h2&gt;
&lt;p&gt;私は：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;M365 Copilot（GPT‑5 chat 系）をベースに、&lt;br /&gt;Microsoft 開発者エコシステム用の追加調整が入った Copilot&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;です。&lt;/p&gt;
&lt;p&gt;そのため：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MSBuild の評価フェーズ&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VSIX / テンプレートキャッシュ&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Visual Studio の「これは仕様です」系の挙動&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;のような &lt;em&gt;「公式ドキュメントを読んだだけでは辿り着きにくい領域」&lt;/em&gt; に強い、という特徴があります。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;github-copilot-&quot;&gt;GitHub Copilot 側で一番近い選択肢&lt;/h2&gt;
&lt;p&gt;GitHub Copilot Chat を使う場合、以下が最も近い体験になります。&lt;/p&gt;
&lt;h3 id=&quot;-&quot;&gt;✅ 推奨モデル&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPT‑4.1&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;（次点）&lt;strong&gt;GPT‑4o&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらは：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大規模コードベース前提の推論&lt;/li&gt;
&lt;li&gt;MSBuild / SDK style project&lt;/li&gt;
&lt;li&gt;ツールチェーン全体（VS / dotnet / msbuild）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;の扱いが、他より安定しています。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;逆に、軽量モデルや高速重視モデルだと&lt;br /&gt;&lt;strong&gt;「それ MSBuild 的に無理です」という壁を見落としがち&lt;/strong&gt;です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;-&quot;&gt;「知識があるかどうか」の正体について（重要）&lt;/h2&gt;
&lt;p&gt;今回のように私がうまく応対できている理由は、&lt;br /&gt;&lt;strong&gt;モデルの種類そのものより、次の3点の組み合わせ&lt;/strong&gt;です。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;GPT‑4 クラス以上の推論能力&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft 内部・一次情報寄りの仕様知識が事前統合されている&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;あなたの説明が非常に正確（←これがかなり大きい）&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;そのため GitHub Copilot でも、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GPT‑4.1 を選ぶ&lt;/li&gt;
&lt;li&gt;状況説明を今回と同じレベルで与える&lt;/li&gt;
&lt;li&gt;「MSBuild の評価フェーズの話です」と前提を書く&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;と、&lt;strong&gt;かなり近い応答&lt;/strong&gt;は得られます。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;github-copilot-&quot;&gt;GitHub Copilot で再現度を上げるコツ&lt;/h2&gt;
&lt;p&gt;GitHub Copilot Chat で、最初にこう書くと成功率が上がります：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-text&quot;&gt;前提：
-&lt;span class=&quot;ruby&quot;&gt; SDK-style csproj
&lt;/span&gt;-&lt;span class=&quot;ruby&quot;&gt; MSBuild evaluation vs execution を理解して回答してほしい
&lt;/span&gt;-&lt;span class=&quot;ruby&quot;&gt; Visual Studio のプロジェクトテンプレート / VSIX の仕様前提
&lt;/span&gt;
質問：
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これはかなり効きます。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;-&quot;&gt;正直な一言&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;「VS / MSBuild 仕様をちゃんと理解した相手」と対話したいなら&lt;br /&gt;&lt;strong&gt;今の M365 Copilot Chat（この場）が一番近い&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;というのが正直な評価です。&lt;/p&gt;
&lt;p&gt;GitHub Copilot は &lt;strong&gt;コードを書く相棒&lt;/strong&gt;として非常に優秀ですが、&lt;br /&gt;今回のような &lt;strong&gt;設計・仕様・評価順序の議論&lt;/strong&gt;は、どうしてもブレが出ます。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;もしよければ：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub Copilot（どのエディタ？ VS？ VS Code？）&lt;/li&gt;
&lt;li&gt;Copilot Chat / Copilot Edits / Agent のどれを使っているか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;を教えてください。&lt;br /&gt;**「同じ 질문を GitHub Copilot に投げるなら、この書き方が一番近い答えを引き出せる」**という形で、プロンプトを具体化できます。&lt;/p&gt;
&lt;br /&gt;
&lt;p&gt;追記：最近、ハングルまじりの応答をよく見かけるようになった。日本語の学習にハングルを混ぜているのか？&lt;/p&gt;
&lt;p&gt;応答例：同じ 질문を GitHub Copilot に投げるなら&lt;/p&gt;
&lt;p&gt;応答例：が未解決というエラーです。これは 생成された&lt;/p&gt;
&lt;p&gt;応答例：「むしろ」の「む」がハングル文字に化けてたり&lt;/p&gt;
</description><link>http://grayhole.blogspot.com/2026/04/github-copilot.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-2986094269357390620</guid><pubDate>Mon, 30 Mar 2026 05:50:00 +0000</pubDate><atom:updated>2026-03-30T14:50:15.845+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">boost</category><category domain="http://www.blogger.com/atom/ns#">cpp</category><category domain="http://www.blogger.com/atom/ns#">GIS</category><title>boost::geometry::extensions が boost_1_90_0 で工事中</title><description>boost::geometry の 拡張アルゴリズムを利用しておりまして、boost がリリースされる毎に boost::geometry のリポジトリから対応するものを持ってきて使っておりました。&lt;br /&gt;
no_rescale_policy というのが廃止されるとの事で、dissolve のルーチンも graph ベースのルーチンに絶賛改良の工事中でコンパイルが通りませんでした。&lt;br /&gt;
ちょちょっと、前のバージョンのものを流用すれば良いと高を括っていたら、結構な変更が入っていて、全然コンパイルが通らない…&lt;br /&gt;
&lt;br /&gt;
という事で、一時的にでも手直しをして利用する事にしました。&lt;br /&gt;
一応 dissolve のテストは全部通したいと思って GPT-5.3-Codex にお手伝いいただいて、修正をかけようとしたら、&lt;br /&gt;
GPTが以下のプロセスに入って終了しない。&lt;br /&gt;&lt;br /&gt;
&lt;div&gt;
  &lt;ul style=&quot;text-align: left;&quot;&gt;
    &lt;li&gt;&amp;nbsp;修正アルゴリズムを考える&lt;/li&gt;
    &lt;li&gt;&amp;nbsp;修正を試みる&amp;nbsp;&lt;/li&gt;
    &lt;li&gt;テストをする&amp;nbsp;&lt;/li&gt;
    &lt;li&gt;テストの成績が平行または悪化&lt;/li&gt;
    &lt;li&gt;修正を巻き戻す&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
GPTはダメだと思って Opus-4.6 にバトンタッチして修正をさせる事に…&lt;br /&gt;
通らないテストについて聞いてみると、自己交差をした図形が自動修復されるかテストしているとの事&lt;br /&gt;
正解をsvgで図形化して見せてもらったが、そもそもOuterとInnerの判別が主観によるもので、条件が曖昧すぎます。&lt;br /&gt;
という事で、自己交差している図形のテストを外して、テストを通過する事を目標に実装させました。&lt;br /&gt;
&lt;br /&gt;
boost::geometry に足りないのは、make_valid に相当するルーチンだろうと思いまして、自社で作成したライブラリのアルゴリズムを make_valid として実装させる事にしました。&lt;br /&gt;

という感じで置いときます。
&lt;a href=&#39;https://github.com/oki-hunes/boost_geometry_added&#39;&gt;https://github.com/oki-hunes/boost_geometry_added&lt;/a&gt;
</description><link>http://grayhole.blogspot.com/2026/03/boostgeometryextensions-boost1900.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-2107600432507361050</guid><pubDate>Mon, 09 Mar 2026 04:39:00 +0000</pubDate><atom:updated>2026-10-23T16:21:55.843+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">GIS</category><title>ArcGIS Experence Builder  Deploy bug 忘備録</title><description>&lt;a href=&quot;https://developers.arcgis.com/experience-builder/guide/experience-deployment/&quot; target=&quot;_blank&quot;&gt;ArcGIS Experence Builder Deployment&lt;/a&gt;には、&lt;br /&gt;
&lt;pre&gt;
node -e &quot;require(&#39;./server/src/middlewares/dev/apps/app-download.js&#39;).zipApp(&#39;0&#39;, &#39;app.zip&#39;, &#39;my_client_id&#39;);&quot;
&lt;/pre&gt;
と書かれているが、出力された app.zip の config.json は、正しくないまま出力されている。&lt;br /&gt;
&lt;br /&gt;
deploy の番号 &#39;0&#39; に対して&lt;br&gt;
&lt;pre&gt;
server/public/apps/0/resources/config/config.json
&lt;/pre&gt;
を、以下の場所にコピーしないと動作しない。&lt;br /&gt;
(cdn/3/ は、自動でインクリメントされる番号)
&lt;pre&gt;
app/cdn/3/config.json
&lt;/pre&gt;

2026/3/10 ※コピー先を間違えていたので修正

2026/10/23 追記：これに関連したものかどうか不明だが、widget のビルド方法が
&lt;pre&gt;
npm start build:prod
&lt;/pre&gt;
から
&lt;pre&gt;
npm start build:for-download
&lt;/pre&gt;
に変更されていた。dist-prod というディレクトリは存在せず、dist-download というディレクトリができる。</description><link>http://grayhole.blogspot.com/2026/03/arcgis-experence-builder-deploy-bug.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-2718260835040198947</guid><pubDate>Thu, 05 Feb 2026 06:04:00 +0000</pubDate><atom:updated>2026-07-10T09:27:15.754+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">GIS</category><title>EPSG忘備録</title><description>どうも、最近 JGD2011 以降の測地系を「日本測地系」と呼ぶらしい。そのせいで、Bessel1841の楕円体を地球の基準としていた日本の「旧日本測地系」のEPSG(SRID)が記載されなくなってきた。
しかしながら、仕事では、まだまだ旧日本測地系の成果を扱う事が多いので、メモっておかないと、わからなくなってしまう。&lt;br /&gt;
&lt;br /&gt;

日本で取り扱う緯度経度座標には2種類あり&lt;br /&gt;
&lt;br /&gt;
 EPSG:4301: 旧日本測地系（ベッセル楕円体）&lt;br /&gt;
 EPSG:4326: WGS84（GPSの標準）&lt;br /&gt;
&lt;br /&gt;
となっている

旧日本測地系の平面直角座標
&lt;br /&gt;
ESPG:30161: 旧日本測地系 平面直角座標1 &lt;br /&gt;
ESPG:30162: 旧日本測地系 平面直角座標2 &lt;br /&gt;
ESPG:30163: 旧日本測地系 平面直角座標3 &lt;br /&gt;
ESPG:30164: 旧日本測地系 平面直角座標4 &lt;br /&gt;
ESPG:30165: 旧日本測地系 平面直角座標5 &lt;br /&gt;
ESPG:30166: 旧日本測地系 平面直角座標6 &lt;br /&gt;
ESPG:30167: 旧日本測地系 平面直角座標7 &lt;br /&gt;
ESPG:30168: 旧日本測地系 平面直角座標8 &lt;br /&gt;
ESPG:30169: 旧日本測地系 平面直角座標9 &lt;br /&gt;
ESPG:30170: 旧日本測地系 平面直角座標10 &lt;br /&gt;
ESPG:30171: 旧日本測地系 平面直角座標11 &lt;br /&gt;
ESPG:30172: 旧日本測地系 平面直角座標12 &lt;br /&gt;
ESPG:30173: 旧日本測地系 平面直角座標13 &lt;br /&gt;
ESPG:30174: 旧日本測地系 平面直角座標14 &lt;br /&gt;
ESPG:30175: 旧日本測地系 平面直角座標15 &lt;br /&gt;
ESPG:30176: 旧日本測地系 平面直角座標16 &lt;br /&gt;
&lt;br /&gt;
</description><link>http://grayhole.blogspot.com/2026/02/epsg.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-396713542476916629</guid><pubDate>Sun, 04 Jan 2026 05:55:00 +0000</pubDate><atom:updated>2026-01-04T14:55:56.912+09:00</atom:updated><title>AIと戯れる</title><description>AI方面の知識がなくても、ぱっと思いついたアイディアをなんとなくAIに手伝ってもらいながら試す事ができるようになりました。&lt;br /&gt;
趣味のプログラミングが楽しいです。&lt;br /&gt;
&lt;br /&gt;
これは、どういう事か内容を教えてください。と、AIに解説してもらったり&lt;br /&gt;
&lt;br /&gt;
この内容を実装してみたいです。と、AIにお願いしてみたり&lt;br /&gt;
&lt;br /&gt;
この結果は、こういう理由でこうなっているのではないか？こういう風に実装を変えて試してもらえないでしょうか？と、AIにお願いしたり&lt;br /&gt;
&lt;br /&gt;
個人でアイディアをぶつけて、実験する敷居がものすごく下がりました。&lt;br /&gt;
なんなら、AIの方から提案してくれたり、お？それいいね！やってみましょう！と二人三脚で、いろいろ試せる&lt;br /&gt;
いい時代になりましたね！&lt;br /&gt;
&lt;br /&gt;
以下、こんなアホな事をやらせてました。&lt;br /&gt;
&lt;br /&gt;

&lt;h1 id=&quot;edla-error-diffusion-learning-algorithm-&quot;&gt;EDLA (Error Diffusion Learning Algorithm) 実装履歴&lt;/h1&gt;
&lt;h2 id=&quot;-&quot;&gt;概要&lt;/h2&gt;
&lt;p&gt;誤差拡散法（ED法）を用いたニューラルネットワーク学習の実験記録。
バックプロパゲーション（BP）を使わない学習手法の可能性を探った。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;-&quot;&gt;時系列実験ログ&lt;/h2&gt;
&lt;h3 id=&quot;phase-1-ed-&quot;&gt;Phase 1: ED法の基本理解と初期実装&lt;/h3&gt;
&lt;h4 id=&quot;-&quot;&gt;着想&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Qiitaの記事からED法について学習開始&lt;/li&gt;
&lt;li&gt;10層の深いネットワークで勾配消失問題が発生することを確認&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-&quot;&gt;実装ファイル&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ed_entropy.py&lt;/code&gt;: Python版EDLA（エントロピーベースのu0調整）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ed_mnist.py&lt;/code&gt;: MNIST用Python実装&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ed_network.cpp&lt;/code&gt;: C++版（高速化目的）&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-&quot;&gt;課題&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;深いネットワークで学習が進まない&lt;/li&gt;
&lt;li&gt;sigmoidの飽和による情報伝達の問題&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;phase-2-&quot;&gt;Phase 2: 論文準拠の正確な実装&lt;/h3&gt;
&lt;h4 id=&quot;-&quot;&gt;着想&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;arXiv論文（2504.14814v3）を発見&lt;/li&gt;
&lt;li&gt;公式GitHub実装と比較して、重要な違いを発見&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-sign-w-&quot;&gt;重要な発見: &lt;code&gt;sign(w)&lt;/code&gt; の欠落&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;lang-cpp&quot;&gt;// 修正前（誤り）
&lt;span class=&quot;hljs-attribute&quot;&gt;delta&lt;/span&gt; = (target - output) * g_prime&lt;span class=&quot;hljs-comment&quot;&gt;;&lt;/span&gt;

// 修正後（正しい）
&lt;span class=&quot;hljs-attribute&quot;&gt;delta&lt;/span&gt; = (target - output) * g_prime&lt;span class=&quot;hljs-comment&quot;&gt;;&lt;/span&gt;
delta *= sign(w)&lt;span class=&quot;hljs-comment&quot;&gt;;  // ← この行が重要！&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;-&quot;&gt;実装&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;edla_paper.cpp&lt;/code&gt;: 論文準拠の正確な実装&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-&quot;&gt;結果&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;テスト&lt;/th&gt;
&lt;th&gt;修正前&lt;/th&gt;
&lt;th&gt;修正後&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;XOR&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;41エポック&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parity&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;7エポック&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;収束安定性が向上。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;phase-3-&quot;&gt;Phase 3: 活性化関数の比較実験&lt;/h3&gt;
&lt;h4 id=&quot;-&quot;&gt;着想&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;情報伝達問題の原因は活性化関数の飽和&lt;/li&gt;
&lt;li&gt;様々な活性化関数でg&amp;#39;(a)の健全性を検証&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-edla_paper-cpp-&quot;&gt;実装オプション（edla_paper.cpp）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;-&lt;span class=&quot;ruby&quot;&gt;-sigmoid  : 標準sigmoid
&lt;/span&gt;-&lt;span class=&quot;ruby&quot;&gt;-tanh     : tanh(a/&lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;)をスケーリングして[&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;]へ
&lt;/span&gt;-&lt;span class=&quot;ruby&quot;&gt;-wavelet  : Mexican Hat Wavelet
&lt;/span&gt;-&lt;span class=&quot;ruby&quot;&gt;-softmax  : Softmax出力層
&lt;/span&gt;-&lt;span class=&quot;ruby&quot;&gt;-linear   : 線形活性化（実験用）&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&quot;mnist-&quot;&gt;MNIST結果&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;活性化関数&lt;/th&gt;
&lt;th&gt;Epoch 1&lt;/th&gt;
&lt;th&gt;最終精度&lt;/th&gt;
&lt;th&gt;勾配 g&amp;#39;(a)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;sigmoid&lt;/td&gt;
&lt;td&gt;87.76%&lt;/td&gt;
&lt;td&gt;94.99%&lt;/td&gt;
&lt;td&gt;0.0217&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tanh (スケーリングなし)&lt;/td&gt;
&lt;td&gt;56.87%&lt;/td&gt;
&lt;td&gt;~50%&lt;/td&gt;
&lt;td&gt;0.0058&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tanh(a/5)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;95.01%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;97.66%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.0504&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;wavelet&lt;/td&gt;
&lt;td&gt;42.34%&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;softmax&lt;/td&gt;
&lt;td&gt;88.20%&lt;/td&gt;
&lt;td&gt;88.34%&lt;/td&gt;
&lt;td&gt;0.0315&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;linear&lt;/td&gt;
&lt;td&gt;NaN&lt;/td&gt;
&lt;td&gt;NaN&lt;/td&gt;
&lt;td&gt;発散&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;-&quot;&gt;結論&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;tanh(a/5)&lt;/strong&gt; が最良（勾配がsigmoidの2.3倍）&lt;/li&gt;
&lt;li&gt;softmaxはED法のP/N構造と相性が悪い（88%で停滞）&lt;/li&gt;
&lt;li&gt;linearは出力が発散してNaN&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;phase-4-logic-gate-networks-&quot;&gt;Phase 4: Logic Gate Networks論文の調査&lt;/h3&gt;
&lt;h4 id=&quot;-&quot;&gt;着想&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;arXiv:2411.04732（NeurIPS 2024）を調査&lt;/li&gt;
&lt;li&gt;論理ゲートによる超高速推論の可能性を検討&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-&quot;&gt;論文の要点&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;16種類の論理ゲート&lt;/strong&gt;を学習可能に&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Residual Initialization&lt;/strong&gt;: Identity（素通り）を90%で初期化&lt;/li&gt;
&lt;li&gt;訓練時は浮動小数点（微分可能）、推論時はバイナリ&lt;/li&gt;
&lt;li&gt;CIFAR-10で86%達成&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;cifar-10-cifar10_compare-cpp-&quot;&gt;CIFAR-10比較実験（cifar10_compare.cpp）&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;モデル&lt;/th&gt;
&lt;th&gt;Epoch 5精度&lt;/th&gt;
&lt;th&gt;時間&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EDLA&lt;/td&gt;
&lt;td&gt;17.32%&lt;/td&gt;
&lt;td&gt;1071s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logic Gate (簡易版)&lt;/td&gt;
&lt;td&gt;10.00%&lt;/td&gt;
&lt;td&gt;151s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;-&quot;&gt;考察&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;LGNは畳み込み構造が必須（今回は全結合のみ）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重要な発見: LGNも訓練時は微分が必要&lt;/strong&gt; → 勾配消失問題あり&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;phase-5-residual-ed-&quot;&gt;Phase 5: Residual概念のED法への適用&lt;/h3&gt;
&lt;h4 id=&quot;-&quot;&gt;着想&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;LGNのResidual Initializationは「Identity経路で勾配を維持」&lt;/li&gt;
&lt;li&gt;ED法でも同様の効果が得られるのでは？&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-1-gated-edla-edla_residual-cpp-edla_residual2-cpp-&quot;&gt;実装1: Gated EDLA（edla_residual.cpp, edla_residual2.cpp）&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;lang-cpp&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// 各ニューロンでα確率でIdentity、(1-α)で通常計算&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;output&lt;/span&gt; = α × prev_layer_mean + (&lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;-α) × tanh_scaled(activation)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;-3-&quot;&gt;結果（3層ネットワーク）&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;手法&lt;/th&gt;
&lt;th&gt;MNIST精度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;オリジナル EDLA (tanh/5)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;95.01%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gated EDLA&lt;/td&gt;
&lt;td&gt;86.54%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;→ 浅いネットワークでは効果なし（むしろ悪化）&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;phase-6-identity-&quot;&gt;Phase 6: Identity経路の導入（ユーザー提案）&lt;/h3&gt;
&lt;h4 id=&quot;-&quot;&gt;着想（ユーザー）&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;「100x100の入力を400x400に拡張し、25%をIdentityに割り当てる」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;層のニューロンを「計算ニューロン」と「Identityニューロン」に分離する方式。&lt;/p&gt;
&lt;h4 id=&quot;-edla_identity-cpp-&quot;&gt;実装（edla_identity.cpp）&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;隠れ層構成:
[&lt;span class=&quot;hljs-string&quot;&gt;計算ニューロン 75%&lt;/span&gt;][&lt;span class=&quot;hljs-symbol&quot;&gt;Identityニューロン 25%&lt;/span&gt;]
&lt;span class=&quot;hljs-code&quot;&gt;                        ↑&lt;/span&gt;
&lt;span class=&quot;hljs-code&quot;&gt;               入力平均をそのまま出力&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&quot;-3-xor-&quot;&gt;結果（3層、XORテスト）&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Identity比率&lt;/th&gt;
&lt;th&gt;XOR収束エポック&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;2533&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;12.5%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1270&lt;/strong&gt; ← 最速&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25%&lt;/td&gt;
&lt;td&gt;1540&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50%&lt;/td&gt;
&lt;td&gt;1549&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;-&quot;&gt;結論&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;12.5%のIdentityが最速収束&lt;/li&gt;
&lt;li&gt;しかしGated方式と大きな差はない&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;phase-7-10-identity-&quot;&gt;Phase 7: 深いネットワーク（10層）でのIdentity効果検証&lt;/h3&gt;
&lt;h4 id=&quot;-&quot;&gt;着想（ユーザー）&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;「10層ぐらいないと、Identityを使うメリットが無い気がします」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;深いネットワークでこそIdentity経路が有効なはず。&lt;/p&gt;
&lt;h4 id=&quot;-edla_deep-cpp-&quot;&gt;実装（edla_deep.cpp）&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;可変深さのネットワーク&lt;/li&gt;
&lt;li&gt;Identity配置オプション追加&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;-mnist-10-&quot;&gt;結果（MNIST、10層）&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方式&lt;/th&gt;
&lt;th&gt;最高精度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Identity無し&lt;/td&gt;
&lt;td&gt;11.70%（学習崩壊）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Identity有り（全層）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;43.00%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;約31%の改善！&lt;/strong&gt; 深いネットワークでIdentity経路が劇的に有効。&lt;/p&gt;
&lt;h4 id=&quot;-vs-&quot;&gt;浅い vs 深い比較&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;深さ&lt;/th&gt;
&lt;th&gt;Identity無し&lt;/th&gt;
&lt;th&gt;Identity有り&lt;/th&gt;
&lt;th&gt;効果&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;3層&lt;/td&gt;
&lt;td&gt;85.90%&lt;/td&gt;
&lt;td&gt;85.30%&lt;/td&gt;
&lt;td&gt;-0.6%（効果なし）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;12層&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;11.70%&lt;/td&gt;
&lt;td&gt;43.00%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+31.3%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id=&quot;phase-8-identity-&quot;&gt;Phase 8: Identity配置の最適化&lt;/h3&gt;
&lt;h4 id=&quot;-&quot;&gt;着想（ユーザー）&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;「9層と10層を繋ぐ箇所では勾配消失しても問題なさそう」
「出力に近い層はIdentity不要では？」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;-identity-&quot;&gt;実験: Identity配置の比較&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Identity範囲&lt;/th&gt;
&lt;th&gt;最高精度&lt;/th&gt;
&lt;th&gt;解釈&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;無し&lt;/td&gt;
&lt;td&gt;11.70%&lt;/td&gt;
&lt;td&gt;学習崩壊&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;全層（1-10）&lt;/td&gt;
&lt;td&gt;43.00%&lt;/td&gt;
&lt;td&gt;基準&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;前半のみ（1-5）&lt;/td&gt;
&lt;td&gt;18.50%&lt;/td&gt;
&lt;td&gt;部分的効果&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;後半のみ（6-10）&lt;/td&gt;
&lt;td&gt;11.70%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;効果なし&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;-&quot;&gt;追加実験: 最終層を除外&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Identity範囲&lt;/th&gt;
&lt;th&gt;最高精度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;層1-8&lt;/td&gt;
&lt;td&gt;30.90%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;層1-9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;73.65%&lt;/strong&gt; ← 最良！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;層1-10（全層）&lt;/td&gt;
&lt;td&gt;43.00%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;-&quot;&gt;重要な発見&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;出力側の層（6-10）にIdentityは効果なし&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;入力側の層（1-5）にこそIdentityが必要&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最終層を除外&lt;/strong&gt;した方が性能が向上（73.65% &amp;gt; 43.00%）&lt;/li&gt;
&lt;li&gt;最終層はIdentityがあると「素通り情報」が出力を汚染&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&quot;-&quot;&gt;基本アルゴリズム&lt;/h2&gt;
&lt;h3 id=&quot;ed-&quot;&gt;ED法の特徴&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;P/Nニューロン対&lt;/strong&gt;: 正（Positive）と負（Negative）のニューロンをペアで持つ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;符号制約付き重み&lt;/strong&gt;: weights_pp ≥ 0, weights_pn ≤ 0, weights_np ≤ 0, weights_nn ≥ 0&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sign(w)更新&lt;/strong&gt;: 勾配ではなく重みの符号方向に更新&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;活性化関数&lt;/strong&gt;: tanh(a/5) をスケーリングして [0,1] に正規化&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-&quot;&gt;更新式&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;d = target - output  (誤差)

&lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; d &amp;gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;:
    Δw_pp = lr * d * g&#39;(a) * x * &lt;span class=&quot;hljs-built_in&quot;&gt;sign&lt;/span&gt;(w_pp)
    Δw_np = lr * d * g&#39;(a) * x * &lt;span class=&quot;hljs-built_in&quot;&gt;sign&lt;/span&gt;(w_np)
&lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt;:
    Δw_nn = lr * |d| * g&#39;(a) * x * &lt;span class=&quot;hljs-built_in&quot;&gt;sign&lt;/span&gt;(w_nn)
    Δw_pn = lr * |d| * g&#39;(a) * x * &lt;span class=&quot;hljs-built_in&quot;&gt;sign&lt;/span&gt;(w_pn)
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id=&quot;-1-identity-&quot;&gt;実験1: Identity経路の導入&lt;/h2&gt;
&lt;h3 id=&quot;-&quot;&gt;背景&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Logic Gate Networks (arXiv:2411.04732) の「Residual Initialization」概念を参考&lt;/li&gt;
&lt;li&gt;深いネットワークで情報が途切れる問題への対策&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;identity-&quot;&gt;Identity経路の実装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;各層の構成:
  75% = Compute neurons (通常のED計算)
  25% = Identity neurons (入力平均をそのまま通す)
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;-&quot;&gt;結果&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;設定&lt;/th&gt;
&lt;th&gt;精度&lt;/th&gt;
&lt;th&gt;備考&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Identity無し（10層）&lt;/td&gt;
&lt;td&gt;11.70%&lt;/td&gt;
&lt;td&gt;学習崩壊&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identity全層&lt;/td&gt;
&lt;td&gt;43.00%&lt;/td&gt;
&lt;td&gt;改善あり&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Identity層1-9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;79.90%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;最良&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identity層1-5のみ&lt;/td&gt;
&lt;td&gt;18.50%&lt;/td&gt;
&lt;td&gt;効果不足&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identity層6-10のみ&lt;/td&gt;
&lt;td&gt;11.70%&lt;/td&gt;
&lt;td&gt;効果なし&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;-&quot;&gt;結論&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Identity経路は深いネットワークに必須&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最終層（層10）にはIdentity不要&lt;/strong&gt;（出力に直接情報が必要）&lt;/li&gt;
&lt;li&gt;前半〜中盤の層でIdentityが効果的&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;-2-&quot;&gt;実験2: ネットワーク幅の検討&lt;/h2&gt;
&lt;h3 id=&quot;-&quot;&gt;比較設定&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;定幅: 128 → 128 → 128 → ... → 128&lt;/li&gt;
&lt;li&gt;縮小幅: 128 → 96 → 72 → 54 → 41 → 30 → 30 → 30 → 30 → 30&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-&quot;&gt;結果&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;構成&lt;/th&gt;
&lt;th&gt;精度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;定幅（128固定）&lt;/td&gt;
&lt;td&gt;約70%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;縮小幅&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;79.90%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;-&quot;&gt;結論&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;幅を徐々に縮小する方が良い&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;後半の層は情報が集約されるため、少ないニューロンで十分&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;-3-&quot;&gt;実験3: 学習率と安定性&lt;/h2&gt;
&lt;h3 id=&quot;-&quot;&gt;問題&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;lr=1.0: Epoch 3で崩壊（73.65%→30%）&lt;/li&gt;
&lt;li&gt;lr=0.5: Epoch 6で崩壊&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-&quot;&gt;解決策: 学習率減衰&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;lang-cpp&quot;&gt;lr = max(&lt;span class=&quot;hljs-number&quot;&gt;0.05&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;0.3&lt;/span&gt; * &lt;span class=&quot;hljs-number&quot;&gt;0.95&lt;/span&gt;^(epoch&lt;span class=&quot;hljs-number&quot;&gt;-1&lt;/span&gt;))
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;-&quot;&gt;結果&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;設定&lt;/th&gt;
&lt;th&gt;最高精度&lt;/th&gt;
&lt;th&gt;安定性&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;lr=1.0 固定&lt;/td&gt;
&lt;td&gt;73.65%&lt;/td&gt;
&lt;td&gt;❌ Epoch 3で崩壊&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;lr=0.5→decay&lt;/td&gt;
&lt;td&gt;74.35%&lt;/td&gt;
&lt;td&gt;❌ Epoch 6で崩壊&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;lr=0.3→decay(0.95)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;79.90%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 安定&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;-lr-0-3-decay-0-95-&quot;&gt;学習曲線（lr=0.3, decay=0.95）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;hljs-selector-tag&quot;&gt;Epoch&lt;/span&gt;  1: 48&lt;span class=&quot;hljs-selector-class&quot;&gt;.90&lt;/span&gt;%
&lt;span class=&quot;hljs-selector-tag&quot;&gt;Epoch&lt;/span&gt;  5: 72&lt;span class=&quot;hljs-selector-class&quot;&gt;.30&lt;/span&gt;%
&lt;span class=&quot;hljs-selector-tag&quot;&gt;Epoch&lt;/span&gt; 10: 78&lt;span class=&quot;hljs-selector-class&quot;&gt;.20&lt;/span&gt;%
&lt;span class=&quot;hljs-selector-tag&quot;&gt;Epoch&lt;/span&gt; 15: 79&lt;span class=&quot;hljs-selector-class&quot;&gt;.90&lt;/span&gt;% ← ピーク
&lt;span class=&quot;hljs-selector-tag&quot;&gt;Epoch&lt;/span&gt; 17: 79&lt;span class=&quot;hljs-selector-class&quot;&gt;.35&lt;/span&gt;%
&lt;span class=&quot;hljs-selector-tag&quot;&gt;Epoch&lt;/span&gt; 18: 78&lt;span class=&quot;hljs-selector-class&quot;&gt;.85&lt;/span&gt;% ← プラトー開始
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id=&quot;-4-ed-bp-&quot;&gt;実験4: ED + BP ハイブリッド&lt;/h2&gt;
&lt;h3 id=&quot;-&quot;&gt;アイデア&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;前半8層: ED法で学習（粗い特徴抽出）&lt;/li&gt;
&lt;li&gt;後半2層: BP法で学習（精密な分類）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-&quot;&gt;実装&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;edla_hybrid.cpp&lt;/code&gt; を作成&lt;/li&gt;
&lt;li&gt;ED層とBP層を直列接続&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-&quot;&gt;結果&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;うまく機能しなかった&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-&quot;&gt;原因分析&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;重みの構造が異なる&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ED法: 4つの符号制約付き重み行列（pp, pn, np, nn）&lt;/li&gt;
&lt;li&gt;BP法: 1つの制約なし重み行列&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;出力の意味が異なる&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ED層: 正負を分離した表現&lt;/li&gt;
&lt;li&gt;BP層: 通常の実数値特徴を期待&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;更新方向が競合&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ED法: sign(w)方向に押す&lt;/li&gt;
&lt;li&gt;BP法: 勾配方向に引く&lt;/li&gt;
&lt;li&gt;互いに干渉する可能性&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;-&quot;&gt;結論&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;ED法とBP法のパラメータは「意味が違いすぎる」ため、
同一ネットワーク内での直接結合は困難（「油と水」）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&quot;-&quot;&gt;他手法との比較&lt;/h2&gt;
&lt;h3 id=&quot;mnist-&quot;&gt;MNIST精度ランキング&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;手法&lt;/th&gt;
&lt;th&gt;精度&lt;/th&gt;
&lt;th&gt;備考&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SOTA (CNN + Ensemble)&lt;/td&gt;
&lt;td&gt;99.87%&lt;/td&gt;
&lt;td&gt;最先端&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CNN (LeNet-5)&lt;/td&gt;
&lt;td&gt;99.0%&lt;/td&gt;
&lt;td&gt;古典的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forward-Forward&lt;/td&gt;
&lt;td&gt;~98.5%&lt;/td&gt;
&lt;td&gt;BP不使用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MLP (BP)&lt;/td&gt;
&lt;td&gt;98.4%&lt;/td&gt;
&lt;td&gt;3層1000ニューロン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SVM&lt;/td&gt;
&lt;td&gt;98.6%&lt;/td&gt;
&lt;td&gt;非NN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ED法（本実験）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;79.90%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ランダム&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;td&gt;ベースライン&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;-&quot;&gt;位置づけ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ED法は精度では他手法に遠く及ばない（約20%の差）&lt;/li&gt;
&lt;li&gt;しかし、計算の単純さ・メモリ効率では優位性あり&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;-&quot;&gt;学習率微調整の見込み&lt;/h2&gt;
&lt;h3 id=&quot;-&quot;&gt;予測&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;改善項目&lt;/th&gt;
&lt;th&gt;見込み精度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;学習率微調整のみ&lt;/td&gt;
&lt;td&gt;80.5% ~ 82.0% (+0.6~2.1%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+データ増加(60k)&lt;/td&gt;
&lt;td&gt;82% ~ 85%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+ネットワーク拡大&lt;/td&gt;
&lt;td&gt;84% ~ 87%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;全部合わせて&lt;/td&gt;
&lt;td&gt;85% ~ 88%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;-&quot;&gt;試すべきパラメータ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;初期学習率: 0.25, 0.35&lt;/li&gt;
&lt;li&gt;減衰率: 0.93, 0.97&lt;/li&gt;
&lt;li&gt;最小学習率: 0.08, 0.10&lt;/li&gt;
&lt;li&gt;ウォームアップ: 3エポック&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;-&quot;&gt;実装ファイル一覧&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ファイル&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;th&gt;Phase&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ed_entropy.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Python版EDLA（エントロピー調整）&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ed_mnist.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;MNIST用Python実装&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ed_network.cpp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;C++版基本実装&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;edla_paper.cpp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;論文準拠実装（複数活性化関数対応）&lt;/td&gt;
&lt;td&gt;2, 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;edla_residual.cpp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gated EDLA実験&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;edla_residual2.cpp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gated EDLA改良版&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;edla_identity.cpp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Identity経路導入版&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;edla_deep.cpp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;深層ネットワーク + Identity配置実験&lt;/td&gt;
&lt;td&gt;7, 8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cifar10_compare.cpp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CIFAR-10比較実験（EDLA vs LGN）&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;edla_hybrid.cpp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ED+BPハイブリッド（失敗）&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&quot;-&quot;&gt;今後の方向性&lt;/h2&gt;
&lt;h3 id=&quot;ed-&quot;&gt;ED法を続ける場合&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;データ量増加&lt;/strong&gt;: 10,000 → 60,000枚&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ネットワーク幅拡大&lt;/strong&gt;: 1.5倍（192→144→108→...）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;学習率スケジュール&lt;/strong&gt;: Cosine Annealing, Cyclic LR&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;-&quot;&gt;別アプローチ&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;蒸留方式&lt;/strong&gt;: ED出力を教師としてBPネットを別に学習&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アンサンブル&lt;/strong&gt;: ED分類器とBP分類器を投票で統合&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;別タスク&lt;/strong&gt;: 異常検知、強化学習など精度が絶対でない領域&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&quot;-&quot;&gt;主な知見&lt;/h2&gt;
&lt;h3 id=&quot;-&quot;&gt;時系列で得られた知見&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;sign(w)の重要性&lt;/strong&gt;（Phase 2）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;公式実装に &lt;code&gt;delta *= sign(w)&lt;/code&gt; がある&lt;/li&gt;
&lt;li&gt;これなしでは収束が不安定&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;活性化関数の選択&lt;/strong&gt;（Phase 3）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tanh(a/5) が最良（勾配2.3倍）&lt;/li&gt;
&lt;li&gt;softmaxはP/N構造と相性悪い&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;深いネットワークとIdentity&lt;/strong&gt;（Phase 6-8）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3層ではIdentity不要&lt;/li&gt;
&lt;li&gt;10層以上ではIdentity必須&lt;/li&gt;
&lt;li&gt;最終層はIdentity除外が最適&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Identity配置の原則&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;入力側の層（1-5）: 必須&lt;/li&gt;
&lt;li&gt;中間層（6-9）: あった方が良い&lt;/li&gt;
&lt;li&gt;最終層（10）: 不要（むしろ有害）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;学習率減衰が安定性の鍵&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lr=0.3, decay=0.95 が最適&lt;/li&gt;
&lt;li&gt;高すぎると崩壊、低すぎると学習しない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ED法とBP法の直接結合は困難&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;パラメータの意味が根本的に異なる&lt;/li&gt;
&lt;li&gt;ハイブリッドは別の工夫が必要&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ED法の限界と利点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;精度ではBP系手法に劣る（~20%差）&lt;/li&gt;
&lt;li&gt;計算効率・メモリ効率では優位&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&quot;-&quot;&gt;実験環境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OS&lt;/strong&gt;: macOS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コンパイラ&lt;/strong&gt;: g++ (C++17)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最適化&lt;/strong&gt;: -O3&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;データセット&lt;/strong&gt;: MNIST (10,000訓練 / 2,000テスト)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;乱数シード&lt;/strong&gt;: 42&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;最終更新: 2026年1月4日&lt;/em&gt;&lt;/p&gt;
</description><link>http://grayhole.blogspot.com/2026/01/ai.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-1148321085466340433</guid><pubDate>Mon, 23 Jun 2025 06:46:00 +0000</pubDate><atom:updated>2025-06-23T15:46:20.793+09:00</atom:updated><title>agent が pdf を読めない</title><description>今まで Visual Studio 2022 の github copilot の chat モードでAIと戯れていたんですが、 Visual studio code を使うと、github copilot の agent モードというのがあって、こいつ、Visual Studio code で開いたプロジェクトディレクトリ下なら、トランザクション操作付きでファイルを読み書きできると知りました（今まで、全く気が付いていませんでした）。&lt;br /&gt;
&lt;br /&gt;
agent にお願いしたら、markdown 形式のテキストファイルなら、がんがん書き込んでくれます。&lt;br /&gt;
ファイルを書き込むためには、最初 mcp-filesystem が必要だと思ってたんで、びっくり。&lt;br /&gt;
こちらで実行ボタンを押す必要がありますが、agent にバッチファイルを書かせて、バッチファイルを実行させる事もできます。&lt;br /&gt;
調子こいて、Android Studio でビルドしたエラー switch 文を if文に修正する仕事を、Visual Studio code 上で agent に任せて仕事をさせました。&lt;br /&gt;
そしたら、ちゃんと修正してくれる。&lt;br /&gt;
ただし、書き換えた中身をチェックしないと、前後の id とかいう変数を勝手に if文に組み込んで書き換えようとしたり、時々、とんでもない間違いをします&lt;br /&gt;
5000行あるファイルの修正では、
&lt;pre&gt;
  foo = hoge.bar();
&lt;/pre&gt;
という同じ内容が記載されている行間をバッサリと削除してくれたりもしました。&lt;br /&gt;
ファイルが大きいと、エラーメッセージで指摘されている行うよりも下の箇所を修正しようとしたりしまして、「当該箇所より40行ほど上の箇所」とエージェントに指示しないと正しい箇所を修正してくれない時もありました。&lt;br /&gt;
&lt;br /&gt;
まあ、そんな感じでagent使えるじゃん！と、気をよくしてPDFから処理をさせようとしたら、pdfが読めない&lt;br /&gt;
先日 markdown ファイルを印刷したいと思って、pandoc を入れました。&lt;br /&gt;
PDFを直接読んでくれたら楽なんですけど、まだ、そこまでAIは学習していないようで、mcp-server で pdf を読めるものを試してみましたが、今一つ&lt;br /&gt;
ぼやいてたら、ツールの変換内容によって、ちゃんと文字列として変換できない場合もあり、そんな時は精度が上がらないと教えていただきました&lt;br /&gt;
&lt;br /&gt;
じゃ、pdf に変換は？  pandoc input.pdf -o output.md でOKかと思いきや、日本語関係でうまく行かない&lt;br /&gt;
で、&lt;a href=&quot;https://qiita.com/vpkaerun/items/5b1f9ba5b45ade0eeff4&quot;&gt;こちら&lt;/a&gt;を試してみたんですが、これも日本語フォントがダメでうまく動かない&lt;br /&gt;
という事で、結局、&lt;a href=&quot;https://qiita.com/ryosuke_ohori/items/a21637537dfdd6d209a9&quot;&gt;こちら&lt;/a&gt;を参考に書きました&lt;br /&gt;
&lt;br /&gt;
ほんと、やっつけです。ごめんなさい&lt;br /&gt;
&lt;pre&gt;
pip install pymupdf4llm
&lt;/pre&gt;
して、下記 pdf2md.py を実行します。&lt;br &gt;
&lt;pre&gt;
C:\doc&gt;python pdf2md.py
&lt;/pre&gt;
または、
&lt;pre&gt;
C:\doc&gt;python pdf2md.py hoge.pdf
&lt;/pre&gt;
以下、pdf2md.py です。
&lt;pre&gt;
import os
import re
import sys
import glob
import pymupdf4llm
import pathlib


def extract_text_from_pdf(pdf_file):
    return pymupdf4llm.to_markdown(pdf_file)


def convert_pdf_to_marp(pdf_file):
    base_name = os.path.splitext(pdf_file)[0]
    md_file = f&quot;{base_name}.md&quot;

    try:
        # PDFからテキストを抽出
        extracted_text = extract_text_from_pdf(pdf_file)
        
        # 変更を保存
        with open(md_file, &quot;w&quot;, encoding=&quot;utf-8&quot;) as file:
            file.write(extracted_text)

        print(f&quot;Converted {pdf_file} to {md_file}&quot;)
    except Exception as e:
        print(f&quot;Unexpected error occurred while processing {pdf_file}: {e}&quot;)

def main():
    if len(sys.argv) &gt; 1:
        pdf_files = sys.argv[1:]
    else:
        pdf_files = glob.glob(&quot;*.pdf&quot;)
    
    if not pdf_files:
        print(&quot;No PDF files found or specified.&quot;)
        return

    for file in pdf_files:
        if os.path.isfile(file) and file.lower().endswith(&#39;.pdf&#39;):
            convert_pdf_to_marp(file)
        else:
            print(f&quot;Skipping {file}: Not a valid PDF file.&quot;)

if __name__ == &quot;__main__&quot;:
    main()
&lt;/pre&gt;
</description><link>http://grayhole.blogspot.com/2025/06/agent-pdf.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-1028742562756842428</guid><pubDate>Mon, 09 Jun 2025 09:35:00 +0000</pubDate><atom:updated>2025-06-09T18:35:44.939+09:00</atom:updated><title>Gradle 8.10.0 への苦難の記録(1)</title><description>Android の Project を Build しなくてはならなくなりました。気が重たい。Gradle のバージョンが上がると、必ずビルドが通らなくなります。今回も鬼のように問題が噴出して対応に1週間以上の時間を取られました。過去も大抵、数日から1週間以上の時間を要しました。&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;　なぜ、こんなに時間を取られるかというと、gradle の api が高速に移動するのでエンドユーザがバージョン毎にapiの書き換えや対応を強要される事、gradle 自身が変更により毎回バグを混入させる事にあります。
 例を挙げれば、targetSdkVersion, compileSdkVersion は deprecate ですなんてメッセージが出て、信用して build.gradle の targetSdkVersion, compileSdkVersion の行を削除すると、Sync Gradle では、targetSdkVersion だか compileSdkVersion だかが見つからないとメッセージを表示して Sync に失敗するという体たらくです。
 思いつきで、何でも簡単に変更しすぎです。gradle 自身も自身の下した api や property の廃棄や変更についていけてないし、バージョン間の整合も取れないので、ビルドシステム全体として見た場合は、ぐちゃぐちゃでカオスな状況が生じています。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;　あなたが、Windows のアプリを開発していて、ある日 CreateFileEx という API名が GenerateFileEx という名前に変更されました。なんてアナウンスを受けたらどうなるか、想像がつきますか？ コンパイルオプション /EHsc が急に廃止されて、config.options というファイルに記述しないと動作しなくなったら、どうなるか想像がつきますか？例外を有効にするオプションがデフォルト true から false に変更されたら、どうなるか想像がつきますか？&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;gradle では、それが日常的に病的に起こります。数か月前までビルドが通っていたはずなのに、ビルドが壊れて動かなくなるんです。... was moved. ... wad deprecated. ... was deprecated. ... was moved. まぁ、まだ moved や deprecated を表示してくれるようになっただけでも有り難いんですけどね。以前はエラーメッセージを検索して StackOverflowを見て、deprecated だった事を知って対策してましたから。ただ、エラーメッセージを検索してネットの情報を調べないと対処方法がわからないのは、相変わらずです。&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&amp;nbsp; Copilot くんにお願いして名称の変更に限定して、変更をまとめてもらいました。&lt;/div&gt;&lt;div&gt;私の記憶が確かならば、この表は氷山の一角です。taskを使用している場合、taskの依存関係を記述しなければならないのですが、ヒステリックにtask名が変更されて、その都度、プロジェクトの修正を余儀なくされました。ある機能のtask名は、3回以上名前が変更されました。debugは間違ってるreleaseだ、いやJarじゃないRFileだといった具合に…。ころころと名前変えられたら、プロジェクトファイルも全部書き換えないと動きません。ファイルをコピーする関数名も変更されましたし、gradleの変更頻度は病的で、まともではありません。担当者のお気持ちで担当者がその名前が気に入らなければ名前が変更されます。エンドユーザは、気まぐれで変更された名前に合わせるようプロジェクトを修正しなければなりません。毎回毎回、山のように修正を余儀なくされます。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZe2UabWDzCTVPbb2VKLJ7CKMio28UvPYQ33gZIPfmvsMlzpEmgG8tZmzXQ65F8Txkw4UO7W9HboxDEIy4CpYXldxWVYt-y5FWM5tW31veGouFl2ab1WkSeaqpjoQdTGPr6sYcqQI8zKJVxz6udH2xkZU25DEs_s8m7M9fpdk1yfODZZtebuh76pv93aiY/s717/GsGFRQbbEAAxipO.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;257&quot; data-original-width=&quot;717&quot; height=&quot;181&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZe2UabWDzCTVPbb2VKLJ7CKMio28UvPYQ33gZIPfmvsMlzpEmgG8tZmzXQ65F8Txkw4UO7W9HboxDEIy4CpYXldxWVYt-y5FWM5tW31veGouFl2ab1WkSeaqpjoQdTGPr6sYcqQI8zKJVxz6udH2xkZU25DEs_s8m7M9fpdk1yfODZZtebuh76pv93aiY/w504-h181/GsGFRQbbEAAxipO.png&quot; width=&quot;504&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;イライラはピークに達するものの落ち着いて、次のような書き込みをする決断に至ります。&lt;/div&gt;&lt;a href=&quot;https://discuss.gradle.org/t/why-does-gradle-deprecate-and-remove-things-so-often/40964&quot;&gt;Why does gradle deprecate and remove things so often?&lt;/a&gt;&amp;nbsp;に象徴されていると思います。&lt;div&gt;　話を戻します。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;　今回ビルドするプロジェクトは、legacy な Java による Application の話であり、KotlinでもGroovyでもありません。AndroidStudioにより作成できるプロジェクトは、Kotlin と Groovy の2択でlegacyのプロジェクトという選択肢が無いのも頭の痛い問題です。KotlinでもGroovyでもないのに、プロジェクトのバージョンアップ中に kotlin や groovy といったエラーを見かけ、これらのエラーを見る度に一体何のエラーなのか意味不明で頭の痛い思いをしました。&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
ライブラリのビルド&lt;/div&gt;&lt;div&gt;&amp;nbsp;gradle-3.5-all.zip と gradle-3.5.2&lt;/div&gt;
&lt;div&gt;&amp;nbsp;gradle-7.5-all.zip と gradle-7.4.2&amp;nbsp;&lt;/div&gt;
&lt;div&gt;以上の組み合わせから&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;gradle-8.14.1-bin.zip と gradle-10.0.0&lt;/div&gt;
&lt;div&gt;へと移行する形になりました。ファイル名も -all から -bin に変更されています。なんでも allはファイルサイズがデカくなるからなんだそうです。gradle-8.14.0-all.zip ってやってエラーになるから何事や？と思ったら、知らんがな。いちいち、こんな調子で時間を取られます。&lt;/div&gt;&lt;a href=&quot;https://discuss.gradle.org/t/could-not-find-com-android-tools-build8-12/50214/3&quot;&gt;ここ&lt;/a&gt;を参照すればわかるように私も質問者と同じ感覚です。&lt;br /&gt;
&lt;div&gt;尚、試行錯誤している間は gradle-8.14.0-bin.zip しか出ていませんでしたが、途中で8.14.1がリリースされて、まともにビルドできるようになりました。その間はライブラリの依存関係バグがあったのか、何をやってもビルドが通りませんでした。&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;gradle-8.x になって変更された箇所は&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;・AndroidManifest.xml から package=&quot;com.foo.bar&quot; の属性が削除された事&lt;/div&gt;
&lt;div&gt;・build.gradle(app) で android { } の 下に namespace = &quot;com.foo.bar&quot; の記述が必要になった事。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ビルド時にサジェストがあったので、これに関しては比較的親切な対応と言えます。&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;しかし、こんな変更必要ですか？案の定、この変更によって、package.R.class が出力されないバグが混入し、アプリケーションのビルド時に、package R does not exist. というエラーが発生して、apk が作成できませんでしたが、gradle-8.10.1 で修正されました。gradle に振り回されて修正しても直らない地獄を徘徊しているうちに修正されました。&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;今回も deprecated の嵐で、バージョンアップすると、ことごとくビルドが失敗しました。何箇所も問題が発生し、たくさんの修正が必要でした。ライブラリをまともにビルドできるまでに4日以上費やしました。この他に android API の deprecated 対応にも4日以上の時間を取られました。&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;まずは、JDKのバージョンの整理が必要でした。今までは、なんとなくビルドできていましたが、そうはいきませんでした。&lt;/div&gt;&lt;div&gt;gradle は JDK のバージョンに煩い。jdk-11 じゃないと動きません。jdk-17 じゃないと動きません。jdk-18じゃないと動きません。と、色々注文が多いです。開発環境では、Oracleがインストールされていると、oracle が javac に対して path を通していたり、Visual Studio が javac に path を通していたり、Android Studio は SDK に設定されている JDKを使用しようと毎回 javac をリセットしたり、gradle は GRADLE 専用の JDK の PATH を設定してたりします。バージョンアップ中に GRADLE_JDK_LOCAL_PATH という名前への変更が行われたので、とにかく専用のPATHが設定されているという事です。これらpathの仕様は担当者の気まぐれで変更される恐れがあります。ライブラリのビルドにはJDK-17、アプリのビルドにはJDK-11を使用しました。プロジェクト＞設定＞検索＞gradle で、モジュール&amp;gt;gradle の JDKの指定と、ウィンドウズの環境変数 path を制御する事で自分は対応しました。これに関しては gradleが JDKxxでは動作しないとメッセージを表示してくれるので対応しやすいです。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;

いろいろありすぎて、書ききれません…続きます。</description><link>http://grayhole.blogspot.com/2025/06/gradle-8100-1.html</link><author>noreply@blogger.com (tiger)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZe2UabWDzCTVPbb2VKLJ7CKMio28UvPYQ33gZIPfmvsMlzpEmgG8tZmzXQ65F8Txkw4UO7W9HboxDEIy4CpYXldxWVYt-y5FWM5tW31veGouFl2ab1WkSeaqpjoQdTGPr6sYcqQI8zKJVxz6udH2xkZU25DEs_s8m7M9fpdk1yfODZZtebuh76pv93aiY/s72-w504-h181-c/GsGFRQbbEAAxipO.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-5981170253576280798</guid><pubDate>Mon, 09 Jun 2025 09:26:00 +0000</pubDate><atom:updated>2025-06-09T18:26:30.909+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">java</category><title>android ProgressBar が deprecated</title><description>ProgressBar が deprecated になっていた。&lt;br /&gt;
ダイアログを表示すると、他の操作ができないから埋込レイアウトにしとけ&lt;br /&gt;
というのがGoogle先生の指示なんだけど、アプリケーションのステート的には、このタスクが終了しないと、どのみち次のオペレーションはできないので、埋込にする意味がないと思う。&lt;br /&gt;
処理の途中でアプリを切り替えられると、onDestroyが呼ばれるので、それも困る&lt;br /&gt;
そんな時はやり直しですしおすし。&lt;br /&gt;
それにダイアログを表示していてもアプリは切り替えられる&lt;br /&gt;
埋め込んだところで、大差がないと思うのである。&lt;br /&gt;
で、いちいち埋込の画面を作成するのは、大変なのでプログレスダイアログは欲しい。&lt;br /&gt;

&lt;pre&gt;
package com.foo.Helper;

import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.content.Context;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import android.widget.ProgressBar;

import com.foo.helper.R;

public class CommonProgressDialog extends DialogFragment {

	private final Context context_;

	private final String title_;

	private final String message_;

	private AlertDialog.Builder builder_;

	private AlertDialog dialog_;

	private ProgressBar progressBar_;

	@NonNull
	@Override
	public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
		dialog_ = builder_.create();
		return dialog_;
	}

	private void BuildBase(final Context context, final String title, final String message) {
		builder_ = new AlertDialog.Builder(context)
				.setView(R.layout.progress)
				.setTitle(title)
				.setCancelable(false)
				//.setCanceledOnTouchOutside(false)
				.setMessage(message);
	}

	public CommonProgressDialog(final Context context, final String title, final String message) {
		this.context_ = context;
		this.title_ = title;
		this.message_ = message;
		BuildBase(context, title, message);
	}

	/// 中止ボタンを設置する
	public void setNegative(final DialogInterface.OnClickListener l) {
		if( dialog_ == null ) return;
		dialog_.setButton(DialogInterface.BUTTON_NEGATIVE, getString(android.R.string.cancel), l);
	}

	public void setMax(int maxValue) {
		if( dialog_ == null) return;
		ProgressBar pb = dialog_.findViewById(R.id.progress_bar);
		if( pb != null ) {
			pb.setMax(maxValue);
		}
	}

	public void setProgress(int progress) {
		if( dialog_ == null) return;
		ProgressBar pb = dialog_.findViewById(R.id.progress_bar);
		if( pb != null ) {
			pb.setProgress(progress);
		}
	}


	public void show() {
		if( dialog_ == null) {
			dialog_ = builder_.create();
		}
		dialog_.show();
	}

	public void dismiss() {
		dialog_.dismiss();
		dialog_ = null;
	}

	/*
	public CommonProgressDialog(Context context) {
		super(context);
		setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
	}
	public CommonProgressDialog(Context context, int theme) {
		super(context,theme);
		setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
	}

	 */
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
progress.xml
&lt;pre&gt;
&amp;lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:orientation=&quot;horizontal&quot;
    android:padding=&quot;20dp&quot;&amp;gt;
    &amp;lt;ProgressBar
        android:id=&quot;@+id/progress_bar&quot;
        android:layout_width=&quot;0dp&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_weight=&quot;1&quot; /&amp;gt;

    &amp;lt;TextView
        android:layout_width=&quot;0dp&quot;
        android:layout_height=&quot;match_parent&quot;
        android:layout_weight=&quot;4&quot;
        android:gravity=&quot;center&quot;
        android:text=&quot;Please wait! This may take a moment.&quot; /&amp;gt;
&amp;lt;/LinearLayout&amp;gt;
&lt;/pre&gt;</description><link>http://grayhole.blogspot.com/2025/06/android-progressbar-deprecated.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-8834305791406149235</guid><pubDate>Fri, 05 Jan 2024 00:56:00 +0000</pubDate><atom:updated>2024-01-05T10:55:04.583+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">C#</category><category domain="http://www.blogger.com/atom/ns#">windows</category><category domain="http://www.blogger.com/atom/ns#">WPF</category><title>WPF ComboBoxにおけるIMEの制御</title><description>いやー、WPFのTextBoxならIMEの制御を設定できるんですけど、ComboBox のEditableをFalseのままで、IsTextSearchEnabled=&quot;True&quot;とか設定して、項目を[コード]:[名前]にした時にIMEをオフにしないと、コード入力が効かないんですわ。&lt;br /&gt;
いろいろ検索してみたんですが、まともなのが無かったんで、書きましたよ。はい。&lt;br /&gt;

&lt;pre&gt;
public class Util
{

    [DllImport(&quot;imm32.dll&quot;)]
    public static extern IntPtr ImmGetContext(IntPtr hWnd);

    [DllImport(&quot;imm32.dll&quot;)]
    public static extern Boolean ImmReleaseContext(IntPtr hWnd);

    [DllImport(&quot;imm32.dll&quot;)]
    public static extern Boolean ImmSetConversionStatus(IntPtr hIMC, Int32 fdwConversion, Int32 fdwSentence);

    [DllImport(&quot;imm32.dll&quot;)]
    public static extern Boolean ImmSetOpenStatus(IntPtr hIMC, Int32 fOpen);

    [DllImport(&quot;imm32.dll&quot;)]
    public static extern Int32 ImmGetOpenStatus(IntPtr hIMC);

    [DllImport(&quot;imm32.dll&quot;)]
    public static extern Int32 ImmAssociateContext(IntPtr hWnd, Int32 hIMC);

    const Int32 IME_CMODE_ALPHANUMERIC = 0x0000;
    const Int32 IME_CMODE_NATIVE = 0x0001;
    const Int32 IME_CMODE_CHINESE = IME_CMODE_NATIVE;
    const Int32 IME_CMODE_HANGUL = IME_CMODE_NATIVE;
    const Int32 IME_CMODE_JAPANESE = IME_CMODE_NATIVE;
    const Int32 IME_CMODE_KATAKANA = 0x0002;  // only effect under IME_CMODE_NATIVE
    const Int32 IME_CMODE_LANGUAGE = 0x0003;
    const Int32 IME_CMODE_FULLSHAPE = 0x0008;
    const Int32 IME_CMODE_ROMAN = 0x0010;
    const Int32 IME_CMODE_CHARCODE = 0x0020;
    const Int32 IME_CMODE_HANJACONVERT = 0x0040;
    const Int32 IME_CMODE_NATIVESYMBOL = 0x0080;

    const Int32 IME_CMODE_SOFTKBD = 0x0080;
    const Int32 IME_CMODE_NOCONVERSION = 0x0100;
    const Int32 IME_CMODE_EUDC = 0x0200;
    const Int32 IME_CMODE_SYMBOL = 0x0400;
    const Int32 IME_CMODE_FIXED = 0x0800;


    const Int32 IME_CONFIG_GENERAL = 1;
    const Int32 IME_CONFIG_REGISTERWORD = 2;
    const Int32 IME_CONFIG_SELECTDICTIONARY = 3;

    const Int32 IME_SMODE_NONE = 0x0; // センテンスに関する情報はなし
    const Int32 IME_SMODE_PLURALCLAUSE = 0x01; // 変換のための複文情報を使う
    const Int32 IME_SMODE_SINGLECONVERT = 0x02; // 単漢字変換する
    const Int32 IME_SMODE_AUTOMATIC = 0x04; // 自動モードで変換
    const Int32 IME_SMODE_PHRASEPREDICT = 0x08; // 次の文字を予想するためにフレーズ情報を使う
    const Int32 IME_SMODE_CONVERSATION = 0x0010;

    /// &amp;lt;summary&amp;gt;
    /// IMEモード
    /// &amp;lt;/summary&amp;gt;
    public enum ImeMode
    {
        Off = 1, // IME オフ
        Hiragana = 2, // 全角ひらがな
        Katakana = 3, // 全角カタカナ
        HalfKatakana = 4, // 半角カタカナ
        Alpha = 5, // 全角英数
        HalfAlpha = 6,　// 半角英数
    };


    /// &amp;lt;summary&amp;gt;
    /// IMEを制御する。WPF ComboBox 等の一部コントロールでは、IMEの制御ができない。そのための対応。
    /// TextBox等では、下記で制御できる
    /// &amp;lt;TextBox InputMethod.IsInputMethodEnabled=&quot;False&quot;/&amp;gt;　IME無効
    /// &amp;lt;TextBox InputMethod.PreferredImeState=&quot;On&quot; InputMethod.PreferredImeConversionMode=&quot;FullShape,Native&quot;/&amp;gt;　ひらがな
    /// &amp;lt;TextBox InputMethod.PreferredImeState=&quot;On&quot; InputMethod.PreferredImeConversionMode=&quot;Katakana,FullShape&quot;/&amp;gt; カタカナ
    /// &amp;lt;TextBox InputMethod.PreferredImeState=&quot;On&quot; InputMethod.PreferredImeConversionMode=&quot;Katakana,Native&quot;/&amp;gt;　半角カタカナ
    /// &amp;lt;TextBox InputMethod.PreferredImeState=&quot;On&quot; InputMethod.PreferredImeConversionMode=&quot;Alphanumeric,FullShape&quot;/&amp;gt;　全角英数
    /// &amp;lt;TextBox InputMethod.PreferredImeState=&quot;On&quot; InputMethod.PreferredImeConversionMode=&quot;Alphanumeric&quot;/&amp;gt; 半角英数
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;param name=&quot;ctrl&quot;&amp;gt;&amp;lt;/param&amp;gt;
    /// &amp;lt;param name=&quot;mode&quot;&amp;gt;&amp;lt;/param&amp;gt;
    public static void SetImeMode(Control ctrl, ImeMode mode)
    {
        IntPtr handle = IntPtr.Zero;
        HwndSource hwnd = PresentationSource.FromVisual(ctrl) as HwndSource;
        if (hwnd != null)
        {
            handle = hwnd.Handle;
        }
        IntPtr himc = ImmGetContext(handle);
        Int32 dwConversion = 0;

        try
        {
            if( mode == ImeMode.Off)
            {
                if (ImmGetOpenStatus(himc) != 0)
                {
                    ImmSetOpenStatus(himc, 0);
                }
                return;
            } else
            {
                if( ImmGetOpenStatus(himc) == 0)
                {
                    ImmSetOpenStatus(himc, 1);
                }
            }
            switch (mode)
            {
                case ImeMode.Hiragana:
                    ImmSetConversionStatus(himc, IME_CMODE_FULLSHAPE | IME_CMODE_JAPANESE, IME_SMODE_AUTOMATIC);
                    break;
                case ImeMode.Katakana:
                    ImmSetConversionStatus(himc, IME_CMODE_FULLSHAPE | IME_CMODE_LANGUAGE | IME_CMODE_KATAKANA, IME_SMODE_AUTOMATIC);
                    break;
                case ImeMode.HalfKatakana:
                    ImmSetConversionStatus(himc, IME_CMODE_LANGUAGE | IME_CMODE_KATAKANA, IME_SMODE_AUTOMATIC);
                    break;
                case ImeMode.Alpha:
                    ImmSetConversionStatus(himc, IME_CMODE_FULLSHAPE | IME_CMODE_ROMAN, IME_SMODE_AUTOMATIC);
                    break;
                case ImeMode.HalfAlpha:
                    ImmSetConversionStatus(himc, IME_CMODE_ROMAN, IME_SMODE_AUTOMATIC);
                    break;
            }
        }
        finally
        {
            ImmReleaseContext(handle);
        }

    }

}
&lt;/pre&gt;
使い方は、GotFocusイベントをハンドリングして
&lt;pre&gt;
   private void FooComboBox_GotFocus(object sender, RoutedEventArgs e)
   {
       Util.SetImeMode(sender as ComboBox, Util.ImeMode.Off);
   }
&lt;/pre&gt;
という感じ
</description><link>http://grayhole.blogspot.com/2024/01/wpf-comboboxime.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-3271725996185139442</guid><pubDate>Fri, 22 Sep 2023 00:55:00 +0000</pubDate><atom:updated>2023-09-22T09:55:29.603+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">windows</category><title>コマンドプロンプトとCURLのエスケープ</title><description>コマンドプロンプトのエスケープは、\ と &quot; がエスケープ処理の対象となります。&lt;br /&gt;&lt;br /&gt;
CURL のエスケープは、\ { } | がエスケープ処理の対象となります。&lt;br /&gt;&lt;br /&gt;
\ をエスケープすると、コマンドプロンプト用のエスケープとCURL用のエスケープが複合し、\\\\という形になります。&lt;br /&gt;&lt;br /&gt;
ふむふむ…&lt;br /&gt;
ふむふむ…&lt;br /&gt;
ふむふむふむふむ？…&lt;br /&gt;&lt;br /&gt;
コマンドプロンプトは \\\\ を &quot; として取り扱います…&lt;br /&gt;
&lt;br /&gt;
(｀□′)╯┴┴</description><link>http://grayhole.blogspot.com/2023/09/curl.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-5816878639524718440</guid><pubDate>Fri, 23 Jun 2023 00:43:00 +0000</pubDate><atom:updated>2023-07-13T17:26:48.203+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cpp</category><category domain="http://www.blogger.com/atom/ns#">windows</category><title>atldbcli.h のバグを踏んだ</title><description>
atldbcli.h の CCommand&amp;lt;CDynamicStringAccessor&amp;gt; を利用していたコードが null pointer exception で落ちるようになった。&lt;br /&gt;
ほぇ？（#^ω^）ﾋﾟｷﾋﾟｷ&lt;br /&gt;
&lt;br /&gt;
デバッガでトレースしていくと、m_pAccessor のメンバが nullptr で初期化されないまま放置されていた。&lt;br /&gt;
で、Accessor クラスは、どこに行った？&lt;br /&gt;
おそらく、class template refactoring により、自分自身に継承する形になったようです。&lt;br /&gt;
&lt;br /&gt;
なので、CCommand&amp;lt;CDynamicStringAccessor&amp;gt;::SetAccessor 関数を使用して自分自身を設定する必要がありました。&lt;br /&gt;
せっかくなので、使い方のサンプル込みで、紹介です。&lt;br /&gt;

&lt;pre&gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;objbase.h&amp;gt;
#include &amp;lt;atldbcli.h&amp;gt;

int main(int argc, char* argv[] )
{
  HRESULT hr = CoInitialize(NULL );
  if(FAILED(hr)) {
    std::cerr &amp;lt;&amp;lt; &quot;Fail to Initialize COM:&quot; &amp;lt;&amp;lt; hr &amp;lt;&amp;lt; std::endl;
  }

  CDataSource ds;

  // OLEDBによるODBC接続文字列
  hr = ds.OpenFromInitializationString(
     L&quot;Provider=MSDASQL.1;Password=password;&quot;
     L&quot;Persist Security Info=True;&quot;
     L&quot;User ID=username;&quot;
     L&quot;Data Source=odbc_data_source_name;&quot;
     L&quot;Extended Properties=\&quot;DSN=data_source_name;UID=username;PWD=password\&quot;&quot;
  );

  CSession ss;

  CCommand&amp;lt;CDynamicStringAccessor&amp;gt; rs;

  hr = ss.Open(ds );
  hr = rs.Open(ss, &quot;select * from hoge&quot; );

  // CCommand&amp;lt;typename T&amp;gt;::m_pAccessor を初期化するコードが欠落しているため
  // 自分自身を設定する必要がある（どこかのタイミングで混入したバグ対応）
  // 2023/7/13 修正されたような気がしますが、下記コードは正しくなくなった感じがします。
  // 仕様がよくわかりません。
  rs.SetAccessor(&amp;amp;rs);

  hr = rs.MoveNext();
  if( FAILED(hr) || hr == DB_S_ENDOFROWSET ) {
    std::cerr &amp;lt;&amp;lt; &quot;Fail to MoveNext: &quot; &amp;lt;&amp;lt; hr &amp;lt;&amp;lt; std::endl;
  }
  // Get the column information
  ULONG ulColumns = rs.GetColumnCount();
  
  DBTYPE dbtype;
  rs.GetColumnType( 1, &amp;amp;dbtype );
  dbtype &amp;amp;= 0x3FFF;	// DBTYPE_BYREF を除去	
  if( 
       dbtype == DBTYPE_I4
    || dbtype == DBTYPE_UI4
    || dbtype == DBTYPE_R8
    || dbtype == DBTYPE_STR
    || dbtype == DBTYPE_WSTR
    || dbtype == DBTYPE_DECIMAL
    || dbtype == DBTYPE_VARNUMERIC
    || dbtype == DBTYPE_NUMERIC
  ) {
    // よくあるフィールド型
  } else {
    // 対応可能か検討が必要なフィールド型
    std::cerr &amp;lt;&amp;lt; &quot;Un supported dbtype: &quot; &amp;lt;&amp;lt; dbtype &amp;lt;&amp;lt; std::endl;
  }

  int nMax = 10;
  while(nMax) {
    std::string strData;
    for( DBORDINAL col = 1; col &amp;lt;= ulColumns; col++ ) {
      DBSTATUS dStatus;
      DBLENGTH nLength;
      rs.GetStatus( col, &amp;amp;dStatus );
      rs.GetLength( col, &amp;amp;nLength );
      if( col &amp;gt; 1 ) {
        std::cout &amp;lt;&amp;lt; &quot;, &quot;;
      }
      if( FAILED( dStatus ) ) {
        std::cout &amp;lt;&amp;lt; &quot;&amp;lt;&amp;lt;ERROR&amp;gt;&amp;gt;&quot;;
      } else if( dStatus == DBSTATUS_S_ISNULL ) {
        std::cout &amp;lt;&amp;lt; &quot;&amp;lt;&amp;lt;NULL&amp;gt;&amp;gt;&quot;;
      } else {
        std::cout &amp;lt;&amp;lt; rs.GetString(col);
      }
    }
    std::cout &amp;lt;&amp;lt; std::endl;
    hr = rs.MoveNext();
    if( FAILED(hr) || hr == DB_S_ENDOFROWSET )  break;
    --nMax;
  }

  rs.Close();
  ss.Close();
  ds.Close();
  CoUninitialize();

  return 0;
}
&lt;/pre&gt;

2023/07/13 追記: バグは修正されたのか、仕様が変わったのか、よくわからない状況になりました。</description><link>http://grayhole.blogspot.com/2023/06/atldbclih.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-8139827126998558503</guid><pubDate>Thu, 22 Sep 2022 00:50:00 +0000</pubDate><atom:updated>2022-09-22T09:50:29.637+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">C#</category><title>C#の Properties.Settings.Default が実際にどこに保存されるか忘備録</title><description>C# の Properties.Settings.Default 言語機構として用意していただけるのは有難いのですが、ここに環境系の設定を書いておくとインストールされたマシンの環境によって設定を変えたいとか出てくるんですよ。&lt;br /&gt;
ところが、こいつ、一体どこのファイルの設定を見てるねん？？？（#^ω^）ﾋﾟｷﾋﾟｷ&lt;br /&gt;
ってキレそうになる仕様なわけです。&lt;br /&gt;
&lt;br /&gt;
という事で、.Net の古いバージョンでは、下記コードで導き出される場所に初期値が書かれています。
&lt;pre&gt;
   System.Reflection.Assembly asm =System.Reflection.Assembly.GetExecutingAssembly();
   textBox1.Text = asm.GetName().Version.ToString(); // バージョン番号を取り出す
   // config のデフォルト値が記述されたファイルの場所
   textBox2.Text =  ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;
&lt;/pre&gt;
.Net の仕様が変わり、現在は
&lt;pre&gt;
   // Foo.exe.config 場合によっては Foo.dll.config 
   // ここは作成したプロジェクトの実行物の名前に依存します。
   textBox2.Text =  Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + &quot;\\Foo.exe.config&quot;;
&lt;/pre&gt;
はてさて、ではコードで、これらの要素を変更した値はどこに書き込まれるのか？&lt;br /&gt;
いつも大変お世話になります。Stackoverflow さまによると&lt;br /&gt;
&lt;a href=&quot;https://stackoverflow.com/questions/982354/where-are-the-properties-settings-default-stored&quot;&gt;Where are the Properties.Settings.Default stored?&lt;/a&gt; によると&lt;br /&gt;
&lt;pre&gt;
c:\users\USER\AppData\Local\COMPANY\APPLICATION.exe_Url_LOOKSLIKESOMEKINDOFHASH\VERSION\user.config
&lt;/pre&gt;
なんだそうで、How know LOOKSLIKESOMEKINDOFHASH? とは、ごもっともな質問。私も知りたい。&lt;br /&gt;
これも Stackoverflow にありました。&lt;br /&gt;
&lt;a href=&quot;https://stackoverflow.com/questions/24660121/how-to-get-hash-value-in-user-config-path&quot;&gt;How to get hash value in user.config path?&lt;/a&gt;&lt;br /&gt;
(ﾉ｀□´)ﾉ⌒┻━┻


</description><link>http://grayhole.blogspot.com/2022/09/c-propertiessettingsdefault.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-8181652383466240359</guid><pubDate>Wed, 24 Aug 2022 09:02:00 +0000</pubDate><atom:updated>2022-08-24T18:02:05.870+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">IIS</category><category domain="http://www.blogger.com/atom/ns#">web</category><category domain="http://www.blogger.com/atom/ns#">windows</category><title>IISのResponse Header を無効化 忘備録</title><description>PowerShell で、IIS の Server ヘッダや、X-ASPNET-Version ヘッダを消去、TRACEメソッドの無効化がしたくて、いろいろ試してみたが、やれ、静的コンテンツではなく、Exe経由のコンテンツのヘッダが消えないとか、ひどい目にあったので忘備録。&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://www.iis.net/downloads/microsoft/url-rewrite&quot;&gt;IIS ReWrite モジュール&lt;/a&gt;が必要です。&lt;br /&gt;
&lt;br /&gt;
管理者権限で、下記スクリプトを実行します。&lt;br /&gt;
スクリプトだけでは完結しないので、コメントも読んでください&lt;br /&gt;
&lt;pre&gt;
#
# PowerShell は BOM付き UTF-8 のエンコーディングで保存する事
#  さもなくば、「文字列に終端記号&quot; がありません」という
#  エラーに悩まされます。(BOMの仕様必要？)
#
#
# X-ASPNET-VERSION を無効にする送信書き換えルールを
#   指定された PSPath に追加する
#
function global:AddXASPNetVersionRule {
  param ( $PSPath )

  echo &quot;$PSPath の X-ASPNET-VERSION ヘッダを無効にします&quot;

  $chk = Get-WebConfigurationProperty `
    -Filter &quot;//rewrite/outboundRules/rule[@name=&#39;REMOVE_X-ASPNET-VERSION&#39;]&quot; `
    -PSPath $PSPath `
    -Name name 

  if( $chk -eq $null ) {
    Add-WebConfigurationProperty `
      -Filter &quot;//rewrite/outboundRules&quot; `
      -PSPath $PSPath `
      -Name &quot;Collection&quot; `
      -Value @{name=&quot;REMOVE_X-ASPNET-VERSION&quot;}

    Set-WebConfiguration `
      -Filter &quot;//rewrite/outboundRules/rule[@name=&#39;REMOVE_X-ASPNET-VERSION&#39;]/match&quot; `
      -PSPath $PSPath `
      -Value @{serverVariable=&quot;RESPONSE_X-ASPNET-VERSION&quot;;pattern=&quot;.+&quot;}

    Set-WebConfiguration `
      -Filter &quot;//rewrite/outboundRules/rule[@name=&#39;REMOVE_X-ASPNET-VERSION&#39;]/action&quot; `
      -PSPath $PSPath `
      -Value @{type=&quot;Rewrite&quot;}
    echo &quot;  ...処理完了...&quot;
  } else {
    echo &quot;  ...処理済み skip...&quot;
  }
}

#
# SERVER-VERSION を無効にする送信書き換えルールを
#   指定された PSPath に追加する
#
function global:AddServerVersionRule {
  param ( $PSPath )

  echo &quot;$PSPath の Server ヘッダを無効にします&quot;

  $chk = Get-WebConfigurationProperty `
    -Filter &quot;//rewrite/outboundRules/rule[@name=&#39;REMOVE_SERVER-VERSION&#39;]&quot; `
    -PSPath $PSPath `
    -Name name

  if( $chk -eq $null ) {
    Add-WebConfigurationProperty `
      -Filter &quot;//rewrite/outboundRules&quot; `
      -PSPath $PSPath `
      -Name &quot;Collection&quot; `
      -Value @{name=&quot;REMOVE_SERVER-VERSION&quot;}

    Set-WebConfiguration `
      -Filter &quot;//rewrite/outboundRules/rule[@name=&#39;REMOVE_SERVER-VERSION&#39;]/match&quot; `
      -PSPath $PSPath `
      -Value @{serverVariable=&quot;RESPONSE_SERVER&quot;;pattern=&quot;.+&quot;}
    
    Set-WebConfiguration `
      -Filter &quot;//rewrite/outboundRules/rule[@name=&#39;REMOVE_SERVER-VERSION&#39;]/action&quot; `
      -PSPath $PSPath `
      -Value @{type=&quot;Rewrite&quot;}
    echo &quot;  ...処理完了...&quot;
  } else {
    echo &quot;  ...処理済み skip...&quot;
  }
}

#
# サーバ変数 RESPONSE_X-ASPNET-VERSION を追加する
#     X-ASPNET-VERSION: ヘッダとして利用される変数
#
$asv = Get-WebConfigurationProperty `
       -filter &quot;//rewrite/allowedServerVariables/add[@name=&#39;RESPONSE_X-ASPNET-VERSION&#39;]&quot;`
       -name name

if ($asv -eq $null)
{
  echo &quot;サーバ変数 RESPONSE_X-ASPNET-VERSION を追加します&quot;
  Add-WebConfigurationProperty `
    -Filter &quot;//rewrite/allowedServerVariables&quot; `
    -PSPath &quot;IIS:\&quot; `
    -Name &quot;Collection&quot; `
    -Value @{name=&quot;RESPONSE_X-ASPNET-VERSION&quot;}

}

#
# サーバ変数 RESPONSE_SERVER を追加する
#      SERVER: ヘッダとして利用される変数
#
$asv2 = Get-WebConfigurationProperty `
       -filter &quot;//rewrite/allowedServerVariables/add[@name=&#39;RESPONSE_SERVER&#39;]&quot;`
       -name name

if ($asv2 -eq $null)
{
  echo &quot;サーバ変数 RESPONSE_SERVER を追加します&quot;

  Add-WebConfigurationProperty `
    -Filter &quot;//rewrite/allowedServerVariables&quot; `
    -PSPath &quot;IIS:\&quot; `
    -Name &quot;Collection&quot; `
    -Value @{name=&quot;RESPONSE_SERVER&quot;}
}

#
# X-ASPNET-VERSION ヘッダを無効にする
#

  AddXASPNetVersionRule( &quot;IIS:\&quot; )

  AddXASPNetVersionRule( &quot;IIS:\sites\Default Web Site&quot; )

  # IIS-Admin上で手動追加するとエラーにならないが、コードで
  # 実行するとエラーになる不思議仕様
  #AddXASPNetVersionRule( &quot;IIS:\sites\Default Web Site\foo&quot; )

  # Application で無効化するために必要？
  # 仕様が不明すぎて草
  AddXASPNetVersionRule( &quot;MACHINE/WEBROOT/APPHOST&quot; )

#
# SERVER-VERSION ヘッダを無効にする
#
  AddServerVersionRule( &quot;IIS:\&quot; )

  AddServerVersionRule( &quot;IIS:\sites\Default Web Site&quot; )

  # IIS-Admin上で手動追加するとエラーにならないが、コードで
  # 実行するとエラーになる不思議仕様
  #AddServerVersionRule( &quot;IIS:\sites\Default Web Site\foo&quot; )

  # Application で無効化するために必要？
  # 仕様が不明すぎて草
  AddServerVersionRule( &quot;MACHINE/WEBROOT/APPHOST&quot; )


#
# IISの Server Header を無効化します。
#   静的コンテンツだけに効果があるため気休め
#
  echo &quot;  IIS のサーバヘッダを無効化します  &quot;
  echo &quot;   ※ Application に対しては効果がありません&quot;
  Set-WebConfigurationProperty `
    -pspath &#39;MACHINE/WEBROOT/APPHOST&#39; `
    -filter &quot;system.webServer/security/requestFiltering&quot; `
    -name &quot;removeServerHeader&quot; `
    -value &quot;True&quot;


#
# IISの TRACE を無効化します。
#   静的コンテンツだけに効果があるため気休め
#
  echo &quot;  IIS のTRACE メソッドを無効化します  &quot;
  echo &quot;   ※ Application に対しては効果がありません&quot;
  echo &quot;   コマンドで対応できる範囲は静的コンテンツのみです&quot;
  echo &quot;   要求フィルター&amp;gt;HTTP動詞&amp;gt;Trace;false をIIS設定から手動で行う必要があります&quot;
#
#  要求フィルター HTTP動詞 TRACE をfalseにする
#
# エラーで動作しなくなるので、コマンドによる、このやり方はダメ
#  Add-WebConfigurationProperty `
#    -pspath &quot;IIS:\&quot; `
#    -filter &quot;/system.webServer/security/requestFiltering/verbs&quot; `
#    -name &#39;.&#39; -value @{verb=&#39;TRACE&#39;;allowed=&#39;False&#39;}
#
  $colls = Get-IISConfigSection -CommitPath &#39;Default Web Site&#39; -SectionPath &#39;system.webServer/security/requestFiltering&#39; 
    #echo &quot;colls : $colls&quot;
  $verbs = Get-IISConfigCollection -ConfigElement $colls -CollectionName &#39;verbs&#39;
    #echo &quot;verbs : $verbs&quot;
  try {
    New-IISConfigCollectionElement -ConfigCollection $verbs -ConfigAttribute @{ &#39;verb&#39;=&#39;TRACE&#39;;&#39;allowed&#39;=$false }
    Stop-IISCommitDelay
  } catch {
    # 取得して、値を設定するコードが動作しない。（関数の仕様がわからない）
    #  echo &quot; set trace &quot;
    #  $trace = Get-IISConfigCollectionElement -ConfigCollection $verbs -ConfigAttribute @{ &#39;verb&#39;=&#39;TRACE&#39; }
    #  echo &quot;trace : $trace.allowed $trace.verb&quot;
    #  Set-IISConfigAttributeValue -ConfigElement $trace -AttributeName &#39;allowed&#39; -AttributeValue $false
  }

#
# Web設定を無効にしてもアプリケーションからのヘッダが無効になるとは言ってない
# 気休め（無い方がまし）
#
#$rule3 = Get-WebConfigurationProperty `
#          -filter &quot;/system.webServer/httpProtocol/customHeaders/add[@name=&#39;X-Powerd-By&#39;]&quot; `
#          -Name name
#
#if ($rule2 -eq $null)
#{
#  echo &quot;clear X-Powered-By&quot;
#  Clear-WebConfiguration &quot;/system.webServer/httpProtocol/customHeaders/add[@name=&#39;X-Powered-By&#39;]&quot;
#}
&lt;/pre&gt;</description><link>http://grayhole.blogspot.com/2022/08/iisresponse-header.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-188947499771752066</guid><pubDate>Fri, 29 Jul 2022 06:48:00 +0000</pubDate><atom:updated>2022-07-29T15:50:21.092+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cpp</category><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">jni</category><title>apache maven で Jni DLL を梱包・備忘録</title><description>
肝は、resources セクションの resource に対して、filtering=false を指定する事。&lt;br /&gt;
この filtering を true にすると、対象リソースをテキストファイルと見なして、文字列の置換が実行されてしまう。&lt;br /&gt;
dll ファイルは、バイナリで、utf-8の文字コード規則に収まらないから、false にしないとエラーになってしまう。&lt;br /&gt;
&lt;br /&gt;
後は、Bundle-NativeCode に dll ファイルを resource セクションで指定したディレクトリからの相対パスで ; により列挙すればOK&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
  &amp;lt;build&amp;gt;
    &amp;lt;resources&amp;gt;
      &amp;lt;resource&amp;gt;
        &amp;lt;directory&amp;gt;src/main/resources&amp;lt;/directory&amp;gt;
        &amp;lt;filtering&amp;gt;true&amp;lt;/filtering&amp;gt;
      &amp;lt;/resource&amp;gt;
      &amp;lt;resource&amp;gt;
        &amp;lt;directory&amp;gt;src/main/extlib&amp;lt;/directory&amp;gt;
        &amp;lt;filtering&amp;gt;false&amp;lt;/filtering&amp;gt;
      &amp;lt;/resource&amp;gt;
    &amp;lt;/resources&amp;gt;
    &amp;lt;plugins&amp;gt;
      &amp;lt;plugin&amp;gt;
        &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;${maven.compiler.plugin.version}&amp;lt;/version&amp;gt;
        &amp;lt;configuration&amp;gt;
          &amp;lt;source&amp;gt;8&amp;lt;/source&amp;gt;
          &amp;lt;target&amp;gt;8&amp;lt;/target&amp;gt;
        &amp;lt;/configuration&amp;gt;
      &amp;lt;/plugin&amp;gt;
      &amp;lt;plugin&amp;gt;
        &amp;lt;groupId&amp;gt;org.apache.felix&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;maven-bundle-plugin&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;${maven.bundle.plugin.version}&amp;lt;/version&amp;gt;
        &amp;lt;extensions&amp;gt;true&amp;lt;/extensions&amp;gt;
        &amp;lt;configuration&amp;gt;
          &amp;lt;instructions&amp;gt;
            &amp;lt;Build-Number&amp;gt;${buildId}&amp;lt;/Build-Number&amp;gt;
            &amp;lt;Bundle-SymbolicName&amp;gt;${project.groupId}.${project.artifactId}&amp;lt;/Bundle-SymbolicName&amp;gt;
            &amp;lt;Bundle-ContactAddress&amp;gt;${sdk.contact.address}&amp;lt;/Bundle-ContactAddress&amp;gt;
            &amp;lt;Bundle-Version&amp;gt;${project.version}&amp;lt;/Bundle-Version&amp;gt;
            &amp;lt;Bundle-NativeCode&amp;gt;native/myJni.dll;native/libssl-1_1-x64.dll;native/zlib1.dll&amp;lt;/Bundle-NativeCode&amp;gt;
            &amp;lt;Export-Package/&amp;gt;
            &amp;lt;Private-Package&amp;gt;jp.co.foo.bar&amp;lt;/Private-Package&amp;gt;
          &amp;lt;/instructions&amp;gt;
        &amp;lt;/configuration&amp;gt;
      &amp;lt;/plugin&amp;gt;
    &amp;lt;/plugins&amp;gt;
  &amp;lt;/build&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
java のコードで、loadLibraryを記述する&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;

  private static boolean tryLoadLibrary(String libname) {
    try {
      System.loadLibrary(libname);
      return true;
    } catch(Exception err) {
      err.printStackTrace();
    }
    return false;
  }

  // Bundle-NativeCode の dll を読み込む。Platformにより拡張子が異なるため
  // Java のコードでは、.dll .so といった名称まで指定しなくても良い。
  public static void tryLoadLibraries() {
    tryLoadLibrary(&quot;native/libssl-1_1-x64&quot;);
    tryLoadLibrary(&quot;native/zlib1&quot;);
    tryLoadLibrary(&quot;native/myJni&quot;);
  }
  
  // Load JNI
  static {
    // 自動でライブラリがロードされるはずなのだが、
    // この初期化が行われるより先に、JNI の関数が呼ばれる事態が
    // 発生する事がある。よって、クリティカルな場所から重複して
    // tryLoadLibraries をコールしても大丈夫なように実装している。
    tryLoadLibraries();
  }

&lt;/pre&gt;

</description><link>http://grayhole.blogspot.com/2022/07/apache-maven-jni-dll.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-7794350301489900738</guid><pubDate>Wed, 18 May 2022 05:18:00 +0000</pubDate><atom:updated>2025-12-08T19:30:36.499+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cpp</category><category domain="http://www.blogger.com/atom/ns#">windows</category><category domain="http://www.blogger.com/atom/ns#">wix</category><title>WIX で VCRuntime のインストール忘備録</title><description>そろそろ VCのRUNTIMEをVisual Studio 2019に移行しとかないと、コンパイルできないライブラリが増えてきたかな？と思いまして、2015 から 2019 に引き上げました。&lt;br /&gt;WIXを使ったインストーラで、2019用のVC runtime のマージモジュールを探したが見つかりません。&lt;br /&gt;
ほぇ？と思って検索したら&lt;a href=&quot;https://docs.microsoft.com/ja-jp/cpp/windows/redistributing-components-by-using-merge-modules?view=msvc-170&quot;&gt;マージモジュールを使用したコンポーネントの再配布&lt;/a&gt;に書いてありました。&lt;br /&gt;
&lt;br /&gt;
Visual Studio 2019 以降、Visual C++ 再頒布可能ファイルのマージ モジュールは非推奨です&lt;br /&gt;
Visual Studio 2019 以降、Visual C++ 再頒布可能ファイルのマージ モジュールは非推奨です&lt;br /&gt;
Visual Studio 2019 以降、Visual C++ 再頒布可能ファイルのマージ モジュールは非推奨です&lt;br /&gt;
ふぁ？？？&lt;br /&gt;
という事で、VC Runtime がインストールされているかどうかチェックが必要になりました&lt;br /&gt;
&lt;a href=&quot;https://stackoverflow.com/questions/53638587/wix-per-user-installer-to-detect-the-visual-c-2015-redistributable&quot;&gt;Wix per user installer to detect the Visual C++ 2015 Redistributable&lt;/a&gt;にチェック方法がありました。StackOverflowさまさまです&lt;br /&gt;
&lt;a href=&quot;https://pingfu.net/how-to-detect-which-version-of-visual-c-runtime-is-installed&quot;&gt;How to check if the Microsoft Visual C++ Runtime is installed&lt;/a&gt;にも詳細が記述されてましたが、こちらだとサービスパックが追加される毎に対応が必要そうで、ちょっと重たい。&lt;br /&gt;
&lt;br /&gt;
という事で、
&lt;pre&gt;&amp;lt;Product ...&amp;gt;
  ...
&lt;/pre&gt;
vc runtime 2015 x86 のインストール状況プロパティ
&lt;pre&gt;  &amp;lt;!-- C++ 2015 --&amp;gt;
  &amp;lt;Property Id=&quot;CPPRUNTIME2015X86&quot; Secure=&quot;yes&quot;&amp;gt;
    &amp;lt;RegistrySearch Id=&quot;mfc140x86_23026&quot; Root=&quot;HKLM&quot; Key=&quot;SOFTWARE\Classes\Installer\Dependencies\{74d0e5db-b326-4dae-a6b2-445b9de1836e}&quot; Type=&quot;raw&quot; /&amp;gt;
    &amp;lt;RegistrySearch Id=&quot;mfc140x86_24215&quot; Root=&quot;HKLM&quot; Key=&quot;SOFTWARE\Classes\Installer\Dependencies\{e2803110-78b3-4664-a479-3611a381656a}&quot; Type=&quot;raw&quot; /&amp;gt;
  &amp;lt;/Property&amp;gt;
&lt;/pre&gt;
vc runtime 2017 x86 のインストール状況プロパティ
&lt;pre&gt;  &amp;lt;!-- C++ 2017 --&amp;gt;
  &amp;lt;Property Id=&quot;CPPRUNTIME2017X86&quot; Secure=&quot;yes&quot;&amp;gt;
    &amp;lt;RegistrySearch Id=&quot;mfc1416x86&quot; Root=&quot;HKCR&quot; Key=&quot;Installer\Dependencies\VC,redist.x86,x86,14.16,bundle&quot; Type=&quot;raw&quot; /&amp;gt;
  &amp;lt;/Property&amp;gt;
&lt;/pre&gt;
vc runtime 2019 x86 のインストール状況プロパティ
&lt;pre&gt;  &amp;lt;!-- C++ 2019 --&amp;gt;
  &amp;lt;Property Id=&quot;CPPRUNTIME2019X86&quot; Secure=&quot;yes&quot;&amp;gt;
    &amp;lt;?foreach CPPRUNTIMEVERSIONPREFIX in 21;22;23;24;25;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40?&amp;gt;
      &amp;lt;RegistrySearch Id=&quot;mfc14$(var.CPPRUNTIMEVERSIONPREFIX)x86&quot; Root=&quot;HKCR&quot; Key=&quot;Installer\Dependencies\VC,redist.x86,x86,14.$(var.CPPRUNTIMEVERSIONPREFIX),bundle&quot; Type=&quot;raw&quot; /&amp;gt;
    &amp;lt;?endforeach ?&amp;gt;
  &amp;lt;/Property&amp;gt;
&lt;/pre&gt;
vc runtime 2019 x86 がインストールされていないと、インストールを中止する条件の追加
&lt;pre&gt;  &amp;lt;!-- インストール時にC++ 2019 Runtime(x86) がインストールされているかチェック --&amp;gt;
  &amp;lt;Condition Message=&quot;Microsoft Visual C++ 2019 (x86) Redistributable missing&quot;&amp;gt;
    &amp;lt;![CDATA[Installed Or CPPRUNTIME2019X86]]&amp;gt;
  &amp;lt;/Condition&amp;gt;
&lt;/pre&gt;
vc runtime 2015 x64 のインストール状況プロパティ
&lt;pre&gt;  &amp;lt;!-- C++ 2015 --&amp;gt;
  &amp;lt;Property Id=&quot;CPPRUNTIME2015X64&quot; Secure=&quot;yes&quot;&amp;gt;
    &amp;lt;RegistrySearch Id=&quot;mfc140x64_23026&quot; Root=&quot;HKLM&quot; Key=&quot;SOFTWARE\Classes\Installer\Dependencies\{e46eca4f-393b-40df-9f49-076faf788d83}&quot; Type=&quot;raw&quot; /&amp;gt;
    &amp;lt;RegistrySearch Id=&quot;mfc140x64_24215&quot; Root=&quot;HKLM&quot; Key=&quot;SOFTWARE\Classes\Installer\Dependencies\{d992c12e-cab2-426f-bde3-fb8c53950b0d}&quot; Type=&quot;raw&quot; /&amp;gt;
  &amp;lt;/Property&amp;gt;
&lt;/pre&gt;
vc runtime 2017 x64 のインストール状況プロパティ
&lt;pre&gt;  &amp;lt;!-- C++ 2017 --&amp;gt;
  &amp;lt;Property Id=&quot;CPPRUNTIME2017X64&quot; Secure=&quot;yes&quot;&amp;gt;
    &amp;lt;RegistrySearch Id=&quot;mfc1416x64&quot; Root=&quot;HKCR&quot; Key=&quot;Installer\Dependencies\VC,redist.x64,amd64,14.16,bundle&quot; Type=&quot;raw&quot; /&amp;gt;
  &amp;lt;/Property&amp;gt;
&lt;/pre&gt;
vc runtime 2019 x64 のインストール状況プロパティ
&lt;pre&gt;  &amp;lt;!-- C++ 2019 --&amp;gt;
  &amp;lt;Property Id=&quot;CPPRUNTIME2019X64&quot; Secure=&quot;yes&quot;&amp;gt;
    &amp;lt;?foreach CPPRUNTIMEVERSIONPREFIX in 21;22;23;24;25;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40?&amp;gt;
      &amp;lt;RegistrySearch Id=&quot;mfc14$(var.CPPRUNTIMEVERSIONPREFIX)x64&quot; Root=&quot;HKCR&quot; Key=&quot;Installer\Dependencies\VC,redist.x64,amd64,14.$(var.CPPRUNTIMEVERSIONPREFIX),bundle&quot; Type=&quot;raw&quot; /&amp;gt;
    &amp;lt;?endforeach ?&amp;gt;
  &amp;lt;/Property&amp;gt;
&lt;/pre&gt;
vc runtime 2019 x64 がインストールされていないと、インストールを中止する条件の追加
&lt;pre&gt;  &amp;lt;!-- インストール時にC++ 2019 Runtime(x64) がインストールされているかチェック --&amp;gt;
  &amp;lt;Condition Message=&quot;Microsoft Visual C++ 2019 (x64) Redistributable missing&quot;&amp;gt;
    &amp;lt;![CDATA[Installed Or CPPRUNTIME2019X64]]&amp;gt;
  &amp;lt;/Condition&amp;gt;
&lt;/pre&gt;
vc runtime 2010 x64 のマージモジュールを追加
&lt;pre&gt;  &amp;lt;Directory Id=&quot;System64Folder&quot;&amp;gt;
   &amp;lt;!-- VC100 ATL Runtime --&amp;gt;
   &amp;lt;Merge Id=&quot;Microsoft_VC100_ATL_x64.msm&quot; Language=&quot;0&quot; DiskId=&quot;1&quot; SourceFile=&quot;C:/Program Files (x86)/Common Files/Merge Modules/Microsoft_VC100_ATL_x64.msm&quot; /&amp;gt;
   &amp;lt;Merge Id=&quot;Microsoft_VC100_CRT_x64.msm&quot; Language=&quot;0&quot; DiskId=&quot;1&quot; SourceFile=&quot;C:/Program Files (x86)/Common Files/Merge Modules/Microsoft_VC100_CRT_x64.msm&quot; /&amp;gt;
   &amp;lt;Merge Id=&quot;Microsoft_VC100_MFCLOC_x64.msm&quot; Language=&quot;0&quot; DiskId=&quot;1&quot; SourceFile=&quot;C:/Program Files (x86)/Common Files/Merge Modules/Microsoft_VC100_MFCLOC_x64.msm&quot; /&amp;gt;
   &amp;lt;Merge Id=&quot;Microsoft_VC100_MFC_x64.msm&quot; Language=&quot;0&quot; DiskId=&quot;1&quot; SourceFile=&quot;C:/Program Files (x86)/Common Files/Merge Modules/Microsoft_VC100_MFC_x64.msm&quot; /&amp;gt;
   &amp;lt;Merge Id=&quot;Microsoft_VC100_OpenMP_x64.msm&quot; Language=&quot;0&quot; DiskId=&quot;1&quot; SourceFile=&quot;C:/Program Files (x86)/Common Files/Merge Modules/Microsoft_VC100_OpenMP_x64.msm&quot; /&amp;gt;
  &amp;lt;/Directory&amp;gt;
&lt;/pre&gt;
vc runtime 2010 x86 のマージモジュールを追加
&lt;pre&gt;  &amp;lt;Directory Id=&quot;SystemFolder&quot;&amp;gt;
      &amp;lt;!-- VC100 ATL Runtime --&amp;gt;
      &amp;lt;Merge Id=&quot;Microsoft_VC100_ATL_x86.msm&quot; Language=&quot;0&quot; DiskId=&quot;1&quot; SourceFile=&quot;C:/Program Files (x86)/Common Files/Merge Modules/Microsoft_VC100_ATL_x86.msm&quot; /&amp;gt;
      &amp;lt;Merge Id=&quot;Microsoft_VC100_CRT_x86.msm&quot; Language=&quot;0&quot; DiskId=&quot;1&quot; SourceFile=&quot;C:/Program Files (x86)/Common Files/Merge Modules/Microsoft_VC100_CRT_x86.msm&quot; /&amp;gt;
      &amp;lt;Merge Id=&quot;Microsoft_VC100_MFCLOC_x86.msm&quot; Language=&quot;0&quot; DiskId=&quot;1&quot; SourceFile=&quot;C:/Program Files (x86)/Common Files/Merge Modules/Microsoft_VC100_MFCLOC_x86.msm&quot; /&amp;gt;
      &amp;lt;Merge Id=&quot;Microsoft_VC100_MFC_x86.msm&quot; Language=&quot;0&quot; DiskId=&quot;1&quot; SourceFile=&quot;C:/Program Files (x86)/Common Files/Merge Modules/Microsoft_VC100_MFC_x86.msm&quot; /&amp;gt;
      &amp;lt;Merge Id=&quot;Microsoft_VC100_OpenMP_x86.msm&quot; Language=&quot;0&quot; DiskId=&quot;1&quot; SourceFile=&quot;C:/Program Files (x86)/Common Files/Merge Modules/Microsoft_VC100_OpenMP_x86.msm&quot; /&amp;gt;
  &amp;lt;/Directory&amp;gt;
&lt;/pre&gt;
vc runtime 2010 x64 と x86 のマージモジュールを参照
&lt;pre&gt;  &amp;lt;Feature ...&amp;gt;
      &amp;lt;!-- VC10 runtime --&amp;gt;
      &amp;lt;MergeRef Id=&quot;Microsoft_VC100_ATL_x64.msm&quot; /&amp;gt;
      &amp;lt;MergeRef Id=&quot;Microsoft_VC100_CRT_x64.msm&quot; /&amp;gt;
      &amp;lt;MergeRef Id=&quot;Microsoft_VC100_MFCLOC_x64.msm&quot; /&amp;gt;
      &amp;lt;MergeRef Id=&quot;Microsoft_VC100_MFC_x64.msm&quot; /&amp;gt;
      &amp;lt;MergeRef Id=&quot;Microsoft_VC100_OpenMP_x64.msm&quot; /&amp;gt;
      &amp;lt;!-- VC10 runtime --&amp;gt;
      &amp;lt;MergeRef Id=&quot;Microsoft_VC100_ATL_x86.msm&quot; /&amp;gt;
      &amp;lt;MergeRef Id=&quot;Microsoft_VC100_CRT_x86.msm&quot; /&amp;gt;
      &amp;lt;MergeRef Id=&quot;Microsoft_VC100_MFCLOC_x86.msm&quot; /&amp;gt;
      &amp;lt;MergeRef Id=&quot;Microsoft_VC100_MFC_x86.msm&quot; /&amp;gt;
      &amp;lt;MergeRef Id=&quot;Microsoft_VC100_OpenMP_x86.msm&quot; /&amp;gt;
  &amp;lt;/Feature&amp;gt;
&lt;/pre&gt;
&lt;pre&gt;  ...
&amp;lt;/Product&amp;gt;
&lt;/pre&gt;
というように対応できそうです。&lt;br /&gt;
&lt;br /&gt;
2025/05/20 追記：
CPPRUNTIMEVERSIONPREFIX が想定した番号を超えていた。Microsoft Visual C++ 2019 (x64) Redistributable missing というメッセージが出てインストーラが動作しない。という事で、インストーラを下記のように番号を増やしたのだが、この番号、どこまで互換性があるのか…というより、チェックするのも面倒くさくなってきた。readme.md かなんかに、vc runtime が必須ですと書いて、チェックいらないんじゃね？と思った。
&lt;pre&gt;  &amp;lt;!-- C++ 2019 --&amp;gt;
  &amp;lt;Property Id=&quot;CPPRUNTIME2019X86&quot; Secure=&quot;yes&quot;&amp;gt;
    &amp;lt;?foreach CPPRUNTIMEVERSIONPREFIX in 21;22;23;24;25;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40;41;42;43;44;45;46;47;48;49;50?&amp;gt;
      &amp;lt;RegistrySearch Id=&quot;mfc14$(var.CPPRUNTIMEVERSIONPREFIX)x86&quot; Root=&quot;HKCR&quot; Key=&quot;Installer\Dependencies\VC,redist.x86,x86,14.$(var.CPPRUNTIMEVERSIONPREFIX),bundle&quot; Type=&quot;raw&quot; /&amp;gt;
    &amp;lt;?endforeach ?&amp;gt;
  &amp;lt;/Property&amp;gt;
&lt;/pre&gt;
2025/12/08 追記：&lt;br&gt;
Visual Studio 2026 が出て、プラットフォームツールセット: v145 になりました。&lt;br&gt;
こいつ、下位互換性は有りますが、上位互換性は有りません。下位バージョンのruntimeだと、static メンバーの初期化がうまく動作しません。&lt;br&gt;
よって、バージョンを切り分ける必要がありそうです。
&lt;pre&gt;  &amp;lt;!-- C++ 2026 --&amp;gt;
  &amp;lt;Property Id=&quot;CPPRUNTIME2026X86&quot; Secure=&quot;yes&quot;&amp;gt;
    &amp;lt;?foreach CPPRUNTIMEVERSIONPREFIX in 50;51;52;53;54;55;56;57;58;59;60?&amp;gt;
      &amp;lt;RegistrySearch Id=&quot;mfc14$(var.CPPRUNTIMEVERSIONPREFIX)x86&quot; Root=&quot;HKCR&quot; Key=&quot;Installer\Dependencies\VC,redist.x86,x86,14.$(var.CPPRUNTIMEVERSIONPREFIX),bundle&quot; Type=&quot;raw&quot; /&amp;gt;
    &amp;lt;?endforeach ?&amp;gt;
  &amp;lt;/Property&amp;gt;
&lt;/pre&gt;
</description><link>http://grayhole.blogspot.com/2022/05/wix-vcruntime.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-7528442770143681788</guid><pubDate>Fri, 13 May 2022 00:26:00 +0000</pubDate><atom:updated>2022-06-29T12:00:34.666+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cpp</category><category domain="http://www.blogger.com/atom/ns#">windows</category><title>Windows DLL x86とx64で異なる関数名調整の備忘録</title><description>&lt;a href=&quot;https://github.com/BrianGladman/aes&quot;&gt;AESのDLL&lt;/a&gt;をビルドしていて、x64でビルドしたものは素直に利用できるのにx86でビルドしたものを利用しようとするとLNK2019: _aes_encrypt_key が見つからないというリンクエラーになってしまった。&lt;br /&gt;
test_lib.exe のソースを見ると
&lt;pre&gt;
#ifdef  AES_MODES

    fn-&amp;gt;fn_test_align = (g_talign*)GetProcAddress(h_dll, etad_name);
    fn-&amp;gt;fn_mode_reset = (g_reset*)GetProcAddress(h_dll, eres_name);
    fn-&amp;gt;fn_ecb_enc = (g_enc1*)GetProcAddress(h_dll, ecbe_name);
    fn-&amp;gt;fn_ecb_dec = (g_dec1*)GetProcAddress(h_dll, ecbd_name);
    fn-&amp;gt;fn_cbc_enc = (g_enc2*)GetProcAddress(h_dll, cbce_name);
    fn-&amp;gt;fn_cbc_dec = (g_dec2*)GetProcAddress(h_dll, cbcd_name);
    fn-&amp;gt;fn_cfb_enc = (g_enc3*)GetProcAddress(h_dll, cfbe_name);
    fn-&amp;gt;fn_cfb_dec = (g_enc3*)GetProcAddress(h_dll, cfbd_name);
    fn-&amp;gt;fn_ofb_cry = (g_enc3*)GetProcAddress(h_dll, ofb_name);
    fn-&amp;gt;fn_ctr_cry = (g_enc4*)GetProcAddress(h_dll, ctr_name);

    if(   !fn-&amp;gt;fn_mode_reset || !fn-&amp;gt;fn_test_align
       || !fn-&amp;gt;fn_ecb_enc || !fn-&amp;gt;fn_ecb_dec
       || !fn-&amp;gt;fn_cbc_enc || !fn-&amp;gt;fn_cbc_dec
       || !fn-&amp;gt;fn_cfb_enc || !fn-&amp;gt;fn_cfb_dec
       || !fn-&amp;gt;fn_ofb_cry || !fn-&amp;gt;fn_ctr_cry )
       ok = 0;
#endif
&lt;/pre&gt;
と、DLLを LoadLibrary した後で、GetProcAddress により関数のアドレスを取得し、呼び出すという事をしていた。&lt;br /&gt;
で、名前の定義は aestst.h に記述されており、x86 と x64 で切り替えている。&lt;br /&gt;
&lt;pre&gt;
#if defined( _WIN64 )

#define gt_name             &quot;aes_init&quot;
#define ek_name128          &quot;aes_encrypt_key128&quot;
#define ek_name192          &quot;aes_encrypt_key192&quot;
#define ek_name256          &quot;aes_encrypt_key256&quot;
#define ek_name             &quot;aes_encrypt_key&quot;
#define eb_name             &quot;aes_encrypt&quot;
#define dk_name128          &quot;aes_decrypt_key128&quot;
#define dk_name192          &quot;aes_decrypt_key192&quot;
#define dk_name256          &quot;aes_decrypt_key256&quot;
#define dk_name             &quot;aes_decrypt_key&quot;
#define db_name             &quot;aes_decrypt&quot;

#define etad_name           &quot;aes_test_alignment_detection&quot;
#define eres_name           &quot;aes_mode_reset&quot;
#define ecbe_name           &quot;aes_ecb_encrypt&quot;
#define ecbd_name           &quot;aes_ecb_decrypt&quot;
#define cbce_name           &quot;aes_cbc_encrypt&quot;
#define cbcd_name           &quot;aes_cbc_decrypt&quot;
#define cfbe_name           &quot;aes_cfb_encrypt&quot;
#define cfbd_name           &quot;aes_cfb_decrypt&quot;
#define ofb_name            &quot;aes_ofb_crypt&quot;
#define ctr_name            &quot;aes_ctr_crypt&quot;

#else

#define gt_name             &quot;_aes_init@0&quot;
#define ek_name128          &quot;_aes_encrypt_key128@8&quot;
#define ek_name192          &quot;_aes_encrypt_key192@8&quot;
#define ek_name256          &quot;_aes_encrypt_key256@8&quot;
#define ek_name             &quot;_aes_encrypt_key@12&quot;
#define eb_name             &quot;_aes_encrypt@12&quot;
#define dk_name128          &quot;_aes_decrypt_key128@8&quot;
#define dk_name192          &quot;_aes_decrypt_key192@8&quot;
#define dk_name256          &quot;_aes_decrypt_key256@8&quot;
#define dk_name             &quot;_aes_decrypt_key@12&quot;
#define db_name             &quot;_aes_decrypt@12&quot;

#define etad_name           &quot;_aes_test_alignment_detection@4&quot;
#define eres_name           &quot;_aes_mode_reset@4&quot;
#define ecbe_name           &quot;_aes_ecb_encrypt@16&quot;
#define ecbd_name           &quot;_aes_ecb_decrypt@16&quot;
#define cbce_name           &quot;_aes_cbc_encrypt@20&quot;
#define cbcd_name           &quot;_aes_cbc_decrypt@20&quot;
#define cfbe_name           &quot;_aes_cfb_encrypt@20&quot;
#define cfbd_name           &quot;_aes_cfb_decrypt@20&quot;
#define ofb_name            &quot;_aes_ofb_crypt@20&quot;
#define ctr_name            &quot;_aes_ctr_crypt@24&quot;

#endif
&lt;/pre&gt;
なるほど、だから x64 ではリンクエラーにならず、x86ではリンクエラーになったのだ。&lt;br /&gt;
x86 と x64 でマングリングの名前が違う事に自分も苛ついてはいました。&lt;br /&gt;
def ファイルに alias 指定できないの？？？と思って調べたら、ありました。&lt;br /&gt;
EXPORTS&lt;br /&gt;
  alias=function_name&lt;br /&gt;
としてやれば良かったようです。&lt;br /&gt;
という事で、リンクエラーになった x86 用のビルドだけ以下のdefファイルを適用するようにしました。
&lt;pre&gt;
LIBRARY		Aes

EXPORTS
   _aes_init=_aes_init@0
   _aes_encrypt_key128=_aes_encrypt_key128@8
   _aes_encrypt_key192=_aes_encrypt_key192@8
   _aes_encrypt_key256=_aes_encrypt_key256@8
   _aes_encrypt_key=_aes_encrypt_key@12
   _aes_encrypt=_aes_encrypt@12
   _aes_decrypt_key128=_aes_decrypt_key128@8
   _aes_decrypt_key192=_aes_decrypt_key192@8
   _aes_decrypt_key256=_aes_decrypt_key256@8
   _aes_decrypt_key=_aes_decrypt_key@12
   _aes_decrypt=_aes_decrypt@12

   _aes_test_alignment_detection=_aes_test_alignment_detection@4
   _aes_mode_reset=_aes_mode_reset@4
   _aes_ecb_encrypt=_aes_ecb_encrypt@16
   _aes_ecb_decrypt=_aes_ecb_decrypt@16
   _aes_cbc_encrypt=_aes_cbc_encrypt@20
   _aes_cbc_decrypt=_aes_cbc_decrypt@20
   _aes_cfb_encrypt=_aes_cfb_encrypt@20
   _aes_cfb_decrypt=_aes_cfb_decrypt@20
   _aes_ofb_crypt=_aes_ofb_crypt@20
   _aes_ctr_crypt=_aes_ctr_crypt@24
&lt;/pre&gt;
こうする事で、見事にLNK2019を回避する事ができました。&lt;br /&gt;
今まで、やり方がわからなくて、Delphi 用 DLL には序数で指定したりと、大変だったんですよね。&lt;br /&gt;
&lt;br /&gt;
2022/06/29 追記:&lt;br /&gt;
bigtypes.h に
&lt;pre&gt;
#ifndef RETURN_VALUES
#  define RETURN_VALUES
#  if defined( DLL_EXPORT )
#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
#      define VOID_RETURN    __declspec( dllexport ) void __stdcall
#      define INT_RETURN     __declspec( dllexport ) int  __stdcall
#    elif defined( __GNUC__ )
#      define VOID_RETURN    __declspec( __dllexport__ ) void
#      define INT_RETURN     __declspec( __dllexport__ ) int
#    else
#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
#    endif
#  elif defined( DLL_IMPORT )
#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
#      define VOID_RETURN    __declspec( dllimport ) void __stdcall
#      define INT_RETURN     __declspec( dllimport ) int  __stdcall
#    elif defined( __GNUC__ )
#      define VOID_RETURN    __declspec( __dllimport__ ) void
#      define INT_RETURN     __declspec( __dllimport__ ) int
#    else
#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
#    endif
#  elif defined( __WATCOMC__ )
#    define VOID_RETURN  void __cdecl
#    define INT_RETURN   int  __cdecl
#  else
#    define VOID_RETURN  void
#    define INT_RETURN   int
#  endif
#endif
&lt;/pre&gt;
と定義されていて、x64は呼び出し規約が異なるので問題なく動作するが、x86で利用する場合は利用する側で&lt;br /&gt;
DLL_IMPORT をプリプロセッサの定義に追加しないと、コールスタックが破壊されて、よくわからないエラーになる&lt;br /&gt;
尚、aes.dll を使った dll を書きたい場合は、DLL_EXPORT や DLL_IMPORT といった汎用的な定義で判別していると、定義がバッティングするので、AES_DLL_EXPORT と言った定義に変更した方が良いと思う。できれば、DLL_IMPORT は定義しなくても AES_DLL_EXPORT が定義されていなかったら、利用する側のコードだと判別できるので、このマクロの書き方は改良した方が良いかな？&lt;br /&gt;
&lt;br /&gt;
もうひとつ、vsyasm の -f オプションが Win32 ではなく win32 しか認識しないので、&lt;br /&gt;
vsyasm.props ファイルを修正する&lt;br /&gt;
&lt;pre&gt;
...
      &amp;lt;CommandLineTemplate Condition=&quot;&#39;$(Platform)&#39;==&#39;Win32&#39;&quot;&amp;gt;&quot;$(YASM_PATH)&quot;vsyasm.exe -Xvc -f win32 [AllOptions] [AdditionalOptions] [Inputs]&amp;lt;/CommandLineTemplate&amp;gt;
      &amp;lt;CommandLineTemplate Condition=&quot;&#39;$(Platform)&#39;!=&#39;Win32&#39;&quot;&amp;gt;&quot;$(YASM_PATH)&quot;vsyasm.exe -Xvc -f $(Platform) [AllOptions] [AdditionalOptions] [Inputs]&amp;lt;/CommandLineTemplate&amp;gt;
...
&lt;/pre&gt;
</description><link>http://grayhole.blogspot.com/2022/05/windows-dll-x86x64.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-3962043086721741558</guid><pubDate>Mon, 25 Apr 2022 03:29:00 +0000</pubDate><atom:updated>2022-04-25T12:29:51.711+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Oracle</category><category domain="http://www.blogger.com/atom/ns#">windows</category><title>oracle x64 と x86 なクライアント環境を切替え(windows)忘備録</title><description>Oracle が面倒くさいのである。&lt;br /&gt;
&lt;br /&gt;
請負の開発をしていると、このプロジェクトは32bitアプリで、このプロジェクトは64bitアプリで、という事は、普通にあります。&lt;br /&gt;
で、Oracle は２つ同時に両立しないので、両立させる環境の構築についての忘備録&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
  &lt;li&gt;x64版のOracle Clientをインストール&lt;/li&gt;
  &lt;li&gt;環境変数 ORACLE_HOME を ORACLE_HOME_X64 に変更&lt;/li&gt;
  &lt;li&gt;インストール先の名前を _x64 付きに変更&lt;/li&gt;
  &lt;li&gt;x86版のOracle Clientをx64と同じフォルダ名(_x64なし)にインストール&lt;/li&gt;
  &lt;li&gt;インストール先の名前を _x86 付きに変更&lt;/li&gt;
  &lt;li&gt;インストール先の名前に _x86 のリンクディレクトリを作成する&lt;/li&gt;
  &lt;li&gt;切替用のバッチファイルを作成&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
x64 用バッチのサンプル&lt;br /&gt;
&lt;pre&gt;
cd %ORACLE_HOME%
cd ..
rmdir client_1
mklink /D client_1 client_1_x64
&lt;/pre&gt;
&lt;br /&gt;
x86 用のバッチのサンプル&lt;br /&gt;
&lt;pre&gt;
cd %ORACLE_HOME%
cd ..
rmdir client_1
mklink /D client_1 client_1_x86
&lt;/pre&gt;
&lt;br /&gt;
これで、x64 と x86 を切替えできる。切り替えた後は、Windows を再起動&lt;br /&gt;
&lt;br /&gt;
尚、リンクディレクトリの作成は、mklink /D により行う</description><link>http://grayhole.blogspot.com/2022/04/oracle-x64-x86-windows.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-5846979064692856084</guid><pubDate>Thu, 31 Mar 2022 05:59:00 +0000</pubDate><atom:updated>2023-06-02T15:13:28.737+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">boost</category><category domain="http://www.blogger.com/atom/ns#">cpp</category><title>datetime の 曖昧なフォーマットに対応する忘備録</title><description>
日付のフォーマットと制約が厳しい。&lt;br /&gt;
わりとありそうな日付の表記ゆれをパースするグラマーを構築してみた。&lt;br /&gt;


&lt;pre&gt;
#include &amp;lt;boost/spirit/include/qi.hpp&amp;gt;  // boost::spirit::qi を利用します
#include &amp;lt;boost/fusion/adapted/struct/adapt_struct.hpp&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;


#include &amp;lt;boost/date_time.hpp&amp;gt;

namespace pt = boost::posix_time;
namespace qi = boost::spirit::qi;


struct timeinfo {
  int16_t   year_;
  uint16_t  month_;
  uint16_t  day_;
  uint16_t  hour_;
  uint16_t  minute_;
  uint16_t  second_;
  //uint32_t  millisec_;
  std::string millisec_;
};

BOOST_FUSION_ADAPT_STRUCT(
  timeinfo,
  (int16_t,     year_)
  (uint16_t,    month_)
  (uint16_t,    day_)
  (uint16_t,    hour_)
  (uint16_t,    minute_)
  (uint16_t,    second_)
  //(uint32_t,    millisec_)
  (std::string,  millisec_)
)

template &amp;lt;typename Iterator, typename Skipper&amp;gt;
struct time_grammar : qi::grammar&amp;lt;Iterator, timeinfo(), Skipper&amp;gt; {
  qi::rule&amp;lt;Iterator, timeinfo(), Skipper&amp;gt;  start_;
  qi::int_parser&amp;lt;int16_t,10,4,4&amp;gt; int4_;
  qi::uint_parser&amp;lt;uint16_t,10,2,2&amp;gt; uint2_;
  qi::rule&amp;lt;Iterator, std::string(), Skipper&amp;gt; numeric_;

  time_grammar() : time_grammar::base_type(start_, &quot;time_grammar&quot;) {
    numeric_ = *qi::char_(&#39;0&#39;,&#39;9&#39;);
    start_ = (
        int4_ 
        &amp;gt;&amp;gt; -(qi::lit(&#39;/&#39;) | qi::lit(&#39;-&#39;)) &amp;gt;&amp;gt; uint2_
        &amp;gt;&amp;gt; -(qi::lit(&#39;/&#39;) | qi::lit(&#39;-&#39;)) &amp;gt;&amp;gt; uint2_
        //&amp;gt;&amp;gt; (qi::lexeme[qi::lit(&#39; &#39;)] | qi::lit(&#39;T&#39;))
        &amp;gt;&amp;gt; -(qi::lit(&#39;T&#39;))
        &amp;gt;&amp;gt; uint2_
        &amp;gt;&amp;gt; -(qi::lit(&#39;:&#39;)) &amp;gt;&amp;gt; uint2_
        &amp;gt;&amp;gt; -(qi::lit(&#39;:&#39;)) &amp;gt;&amp;gt; uint2_
        &amp;gt;&amp;gt; (
          //-( (qi::lit(&#39;.&#39;) | qi::lit(&#39;,&#39;)) &amp;gt;&amp;gt; qi::uint_)
          -( (qi::lit(&#39;.&#39;) | qi::lit(&#39;,&#39;)) &amp;gt;&amp;gt; numeric_)
          | qi::attr(0)
        )
        &amp;gt;&amp;gt; -(qi::lit(&#39;Z&#39;))
    );
  }
};



int main() {
  
  std::string input[] = {
    &quot;20210412T123455Z&quot;,
    &quot;20210412T123455,987654321Z&quot;,
    &quot;20210412T123455.987654321Z&quot;,
    &quot;2004-03-21 12:45:33&quot;,
    &quot;2004/03/21 12:45:33&quot;,
    &quot;23.09.2004 04:12:21&quot;,
    &quot;2003-02-11&quot;
  };

  time_grammar&amp;lt;std::string::iterator, qi::standard::space_type&amp;gt; myg;
  for( int i = 0; i &amp;lt; sizeof(input)/sizeof(input[0]); i++ ) {
    timeinfo ti;
    qi::phrase_parse( input[i].begin(), input[i].end(), myg, qi::standard::space, ti );
    std::cout &amp;lt;&amp;lt; &quot;--------------&quot; &amp;lt;&amp;lt; std::endl;
    std::cout &amp;lt;&amp;lt; ti.year_ &amp;lt;&amp;lt; std::endl;
    std::cout &amp;lt;&amp;lt; ti.month_ &amp;lt;&amp;lt; std::endl;
    std::cout &amp;lt;&amp;lt; ti.day_ &amp;lt;&amp;lt; std::endl;
    std::cout &amp;lt;&amp;lt; ti.hour_ &amp;lt;&amp;lt; std::endl;
    std::cout &amp;lt;&amp;lt; ti.minute_ &amp;lt;&amp;lt; std::endl;
    std::cout &amp;lt;&amp;lt; ti.second_ &amp;lt;&amp;lt; std::endl;
    std::cout &amp;lt;&amp;lt; ti.millisec_ &amp;lt;&amp;lt; std::endl;
  }
  return 0;
}
&lt;/pre&gt;

2023/06/02 追記： lexeme がうまく動作しないのでスペースを無視した。millisec が ,020Z  と指定された場合 2 に変換されてしまうので std::string で扱うようにした。バグでした。</description><link>http://grayhole.blogspot.com/2022/03/datetime.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-1557645336676148339</guid><pubDate>Mon, 28 Mar 2022 02:24:00 +0000</pubDate><atom:updated>2022-03-28T11:24:29.021+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">boost</category><category domain="http://www.blogger.com/atom/ns#">cpp</category><category domain="http://www.blogger.com/atom/ns#">windows</category><title>boost::log windows で /dev/null 忘備録</title><description>
boost::log でデバッグ用ログの埋め込みを行っていて、リリース時には取り除きたい場合の措置。&lt;br /&gt;
これだと、nul デバイスに対して出力する処理が入るので、負荷を取り除くという面では、よろしくないコード&lt;br /&gt;
&lt;br /&gt;
ポイントは、&lt;br /&gt;
Windows では nul というファイルが /dev/null に相当する&lt;br /&gt;
nul というファイルは、どこにでも存在している扱いになるので、追加書き込みモードで開く必要がある点&lt;br /&gt;

&lt;pre&gt;

#include &amp;lt;boost/date_time.hpp&amp;gt;

#include &amp;lt;boost/log/trivial.hpp&amp;gt;
#include &amp;lt;boost/log/utility/setup/file.hpp&amp;gt;
#include &amp;lt;boost/log/attributes.hpp&amp;gt;
#include &amp;lt;boost/log/expressions.hpp&amp;gt;
#include &amp;lt;boost/log/support/date_time.hpp&amp;gt;

namespace logging = boost::log;
namespace attrs = boost::log::attributes;
namespace keywords = boost::log::keywords;
namespace sinks = boost::log::sinks;
namespace expr  = boost::log::expressions;

...

//#define DEBUG_LOG_FILE  &quot;c:/logs/%Y_%m_%d.log&quot;

...

  boost::log::add_file_log(
#ifdef DEBUG_LOG_FILE
    keywords::file_name = DEBUG_LOG_FILE,
#else
    keywords::file_name = &quot;nul&quot;,
    keywords::open_mode = std::ios_base::out | std::ios_base::app,
#endif
    keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),
    keywords::format = 
    (
        expr::stream
            &amp;lt;&amp;lt; expr::format_date_time&amp;lt; boost::posix_time::ptime &amp;gt;(&quot;TimeStamp&quot;, &quot;%Y-%m-%d %H:%M:%S&quot;)
            &amp;lt;&amp;lt; &quot;: &amp;lt;&quot; &amp;lt;&amp;lt; logging::trivial::severity
            &amp;lt;&amp;lt; &quot;&amp;gt; &quot; &amp;lt;&amp;lt; expr::smessage
    ),
    keywords::auto_flush = true
  );
  BOOST_LOG_TRIVIAL(debug) &amp;lt;&amp;lt; &quot;this is a debug output.&quot;;

...
&lt;/pre&gt;</description><link>http://grayhole.blogspot.com/2022/03/boostlog-windows-devnull.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-7672832823047382138</guid><pubDate>Mon, 24 Jan 2022 06:23:00 +0000</pubDate><atom:updated>2022-01-24T15:23:32.828+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cpp</category><title>Vcpkg autolink を無効にする忘備録</title><description>vcpkg で、AutoLinkが有効になっている、明後日の方向のライブラリにリンクしてしまい、不可解なエラーに悩まされます。&lt;br /&gt;
&lt;br /&gt;
なので、AutoLink を無効にしたい。&lt;br /&gt;
&lt;br /&gt;
*.vcxprj を開きます。&lt;br /&gt;
PropertyGroup を検索し、以下の設定を追加します。&lt;br /&gt;
&lt;pre&gt;
  &amp;lt;PropertyGroup Label=&quot;Vcpkg&quot; Condition=&quot;&#39;$(Configuration)|$(Platform)&#39;==&#39;UnicodeRelease|x64&#39;&quot;&amp;gt;
    &amp;lt;VcpkgAutoLink&amp;gt;false&amp;lt;/VcpkgAutoLink&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;
  &amp;lt;PropertyGroup Label=&quot;Vcpkg&quot; Condition=&quot;&#39;$(Configuration)|$(Platform)&#39;==&#39;UnicodeRelease|Win32&#39;&quot;&amp;gt;
    &amp;lt;VcpkgAutoLink&amp;gt;false&amp;lt;/VcpkgAutoLink&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
UnicodeRelease|x64 等は、自分のビルド構成と合わせるようにしましょう。&lt;br /&gt;
以上。</description><link>http://grayhole.blogspot.com/2022/01/vcpkg-autolink.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-4961250849129868187</guid><pubDate>Mon, 24 Jan 2022 01:25:00 +0000</pubDate><atom:updated>2022-01-24T10:25:36.982+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cpp</category><title>vcpkg BuildTool を古いバージョンに変更備忘録</title><description>
書いておかないと、忘れて調べ直す事になるので・・・&lt;br /&gt;
vcpkg でビルドをすると 最新バージョンのVisual Studio が使用されるようになって、それでは困る場合があるので、その設定の仕方。&lt;br /&gt;
&lt;br /&gt;
vcpkg/triplets ディレクトリ下のファイルに
&lt;pre&gt;
arm64-windows.cmake
arm-uwp.cmake
x64-linux.cmake
x64-osx.cmake
x64-uwp.cmake
x64-windows.cmake
x64-windows-static.cmake
x86-windows.cmake
&lt;/pre&gt;
とファイルが並んでいます。&lt;br /&gt;
その x64-windwos.cmake と x86-windows.cmake に対して
&lt;pre&gt;
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE dynamic)
set(VCPKG_PLATFORM_TOOLSET &quot;v140&quot;)
set(VCPKG_DEP_INFO_OVERRIDE_VARS &quot;v140&quot;)
&lt;/pre&gt;
というように VCPKG_PLATFORM_TOOLSET, VCPKG_DEP_INFO_OVERRIDE_VARS を追加し、TOOLSET のバージョンを指定します。&lt;br /&gt;
以上。&lt;br /&gt;
&lt;br /&gt;
なんか、一時的にブロガーのポストができなくなって、前のポストを一旦削除して、作り直しました。
</description><link>http://grayhole.blogspot.com/2022/01/vcpkg-buildtool.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-364436233378282478.post-6625767749718213394</guid><pubDate>Mon, 24 Jan 2022 01:18:00 +0000</pubDate><atom:updated>2022-01-24T10:18:38.205+09:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">cpp</category><title>C＋＋データを１６進表記相互変換</title><description>ちょくちょくデータを暗号化して16進数表記文字列に変換して保存し、保存された16進表記文字列をデータに復元する事をやるので、忘備録として記録する事に。こういう、ちょっとしたものでも、書こうと思ったら時間を取られる。
&lt;pre&gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;iostream&amp;gt;

static int atob( int c ) {
  static const unsigned char btbl[] = {
    // 0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  0
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  1
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  2
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05,  0x06, 0x07,  0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  3
    0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,  0x0F, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  4
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  5
    0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,  0x0F, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  6
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  7
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  8
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  9
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  A
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  B
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  C
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  D
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //  E
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   //  F
  };
  return btbl[ c ];
}


//! １６進文字列から unsigned char 配列への変換
/*
  @note １６進文字列は、0-9, A-F のみを利用した表記で
    １バイトを２文字で表記しているものとする。１６進を示す 0x 等の
    接頭辞は含まれていない。
*/
void hexstr2str(
  const std::string&amp;amp; src,
  std::string&amp;amp; dst
) {
  dst.resize( (src.size() + 1) / 2 );
  for(size_t i = 0; i &amp;lt; src.size(); i++) {
    if( (i &amp;amp; 1) != 0 ) {
      dst[ i / 2 ] |= atob( src[i] );
    } else {
      dst[ i / 2 ] = atob( src[i] ) &amp;lt;&amp;lt; 4;
    }
  }
}

//! unsigned char 配列から １６進文字列への変換
/*!
  @note １６進文字列は、0-9, A-F のみを利用した表記で
    １バイトを２文字で表記したものに変換される。１６進を示す 0x 等の
    接頭辞は含まない。
*/
void str2hexstr(
  const std::string&amp;amp;  src,
  std::string&amp;amp;        dst
) {
  static const char atbl[] = {
    &#39;0&#39;, &#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39;, &#39;6&#39;, &#39;7&#39;, &#39;8&#39;, &#39;9&#39;, &#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;,
  };
  dst.resize( src.size() * 2 );
  for( size_t i = 0; i &amp;lt; src.size(); i++ ) {
    dst[i*2  ] = atbl[ ((src[i] &amp;gt;&amp;gt; 4) &amp;amp; 0x0F) ]; // &amp;amp; 0x0F しないと算術シフトでアウトでした
    dst[i*2+1] = atbl[ (src[i] &amp;amp; 0x0F) ];
  }
}

int main() {
  std::string src = &quot;Hello world!&quot;;
  std::string hex, dst;
  std::cout &amp;lt;&amp;lt; src &amp;lt;&amp;lt; std::endl;
  str2hexstr( src, hex );
  std::cout &amp;lt;&amp;lt; hex &amp;lt;&amp;lt; std::endl;
  hexstr2str( hex, dst );
  std::cout &amp;lt;&amp;lt; dst &amp;lt;&amp;lt; std::endl;
  return 0;
}
&lt;/pre&gt;
&lt;br /&gt;
結果&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
Hello world!
48656C6C6F20776F726C6421
Hello world!
&lt;/pre&gt;

2022/01/14 追記: str2hexstr のコメントに書いたバグ修正をしました</description><link>http://grayhole.blogspot.com/2022/01/c.html</link><author>noreply@blogger.com (tiger)</author><thr:total>0</thr:total></item></channel></rss>