P / Invokeおよび64ビット開発

最近、私のWPFアプリケーションでは、ClearType後処理が再び必要になりました。 最初に「通常」の方法でレンダリングされるグラフィックにClearTypeのようなプロパティを追加します。 再びアンマネージコード(Intel C ++スタック、OpenMP)が選択されましたが、今回は64ビット環境でやり取りしたかったのです。 これがいかに「楽しい」かという話です。





これらはいくつかの間違った蜂です

私は64ビットC ++ Win32 DLLアプリケーションを意味しています...そしてウィザードがファイルを生成した後に最初に目にするのはこの魅力です:









正直に言うと、x64オプションは、ケースの50%のどこかに構成として表示されますが、これは特に理由はありません。 それでも、Configuration Managerで構成を作成する必要があることを理解するには、インターネットを詳しく調べる必要がありました。 すぐに言ってやった。 x64構成は、原則としてリストから選択できます。









構成の時間を節約することに決め、Win32設定をコピーすることにしました。 構成内のすべての.NetプロジェクトがWin64をターゲットにし始めたことを除いて、 すべてが正常に機能しました 。 しかし、プロジェクトはコンパイルされますが、PostSharpが私と結び付けられていなければ、私は何も知りませんでした。 どういうことができたのかわかりませんが、PostSharpは、画面に収まらないエラーメッセージを含む64ビットのconfで「配信」されました。



構成を手動で変更する必要がありました。



停止、私のdllはどこにありますか?

一般に、DLLをビルドするには、プロジェクトからファイルを開いているときに[プロジェクトのビルド]をクリックするだけでは不十分です。 C#プロジェクト(およびMicrosoft C ++プロジェクト)とは異なり、開いているファイルにはプロジェクトのビルドオプションはありません! ソリューションを右クリックして、[ビルド]を選択する必要があります。 インテルの誰がユーザビリティの責任を負っているのかわかりませんが、これは深刻な問題です。









VSでのC ++開発の新参者を待っている1つのパズルは、DLLが生成されますが、後で見つけることができないということです。 対応するプロジェクトのDebugまたはReleaseフォルダーでDLLを見つけようとすると、これが得られます。









問題は、Visual C ++が特定のプロジェクトではなくDLL自体をソリューションレベルに置くことです。 したがって、上記のいくつかのフォルダーを探してください。 おそらくこれはある種の論理かもしれませんが、ドナーとして私は彼女の主張が空白ではないと思います。



輸入関税を支払う

この時点で、 [DllImport]



は動作を拒否しました。 より正確には、彼は働き始めなかった。 呼び出し規約を正しく登録したにもかかわらず、.Netはラベルを見つけることができませんでした。 Googleで30分を過ごした後、 DllImportは64ビットライブラリを操作できないという結論に達しました。 より正確に動作しますが、 DUMBIN /EXPORTS



を作成し、 DUMBIN /EXPORTS



ようなP / Invokeメソッドの定義を開始した後にのみ:



[DllImport( "Typografix.Bitmap.dll" , <br/>

CallingConvention = CallingConvention.Cdecl, <br/>

ExactSpelling = true , <br/>

EntryPoint = "?Coalesce@@YAXPEAE0HHH@Z" )] // <-- whoops!

public static extern void Coalesce(IntPtr src, IntPtr dst, <br/>

int width, int height, int stride);<br/>







誰もが確かにはっきりしているので、私はここでそのような決定の「優雅さ」についてコメントしません。 残念ながら、この時点ではまだ何も機能しません。



「得点する」欲求があります

超巨大な理想の世界では、収集時の.Netプロジェクトは、別のC ++プロジェクトへの依存関係を登録した場合、依存プロジェクトの作業の結果をDebug / Releaseフォルダーにコピーする必要があることを明確にすることができました。 そして、現実の世界では、主なプロジェクトは、DLLを目的のフォルダーにコピーするポストビルドステップを作成することです。 さらに、これをC ++プロジェクトに対して正確に行うことが望ましいのは、 .Netコンシューマをビルドして起動しても、常にビルド後のステップが開始されるわけではありません 。 この理由は明らかだと思います。



それにもかかわらず、これらすべての操作の後、プロジェクトは機能し始めました。 失望を得て、OpenMPのサポートを追加しました。その後、アプリケーションが「イメージを誤った形式で読み込もうとしました」というエラーで正常にクラッシュしました。 見つけるために 。 同意します。エラーテキストの情報内容は驚くべきものです。特に、何らかの「誤った」形式でDLLを生成し始めたという仮定に基づいてプロジェクト設定を1時間かけて選んだ後は特にそうです。



この状況では、 DUMPBIN



が再び私を救った。 Intel evskyは、MicrosoftコンパイラでOpenMPを使用するのとは異なり、特定のライブラリlibiomp5md.dll



いますlibiomp5md.dll



、当然bin



フォルダ(およびもちろんPATH



変数)にも分類されません。 襲撃中です。 うまくいくようです。



最後の爪

x64ライブラリのコードは32ビットプロジェクトから直接取得されたため、最初は動作しませんでした(ポインター演算の変更により)。 だから、愚かにもDLLにブレークポイントを設定し、アンマネージコードデバッグをオンにしてF5を押しました。 結果?









ここでは、デバッグを機能させるために行った調整とジャンプについては説明しません。 要するに、一番下の行は、DLLの開始プロセスとして管理プログラムを登録することでした。 何度も試みた後、私はこのベンチャーを辞めることにしました。 確かにそのようなデバッグの可能性はありますが、個人的には、この問題が解決される可能性のある2010thスタジオを座って愚かに待つ必要があるように思えます。



ケースを閉じます

何が起こっているのかという不満にもかかわらず、私は図書館を完成させました。 もちろん、高品質のデバッグについて話す必要はありませんが、幸運なことに、アルゴリズム自体は非常にシンプルであり、さらに32ビット環境で既にテストされているため、残っているのはsizeof(void*) != sizeof(DWORD)



。 この記事を書いている間、すべてが機能し、現在はバックグラウンドで機能しています(見出しにはアルゴリズムが使用されています)。 概して、これらのアルゴリズムは.Netの類似物よりも15〜20倍高速に動作します。



私は基本的に、ほとんどのタスクでこれが絶対にオプションである場合、64ビット開発に今行くべきではないことを基本的に理解しています。 熊手を触ってみたかっただけです。 そして、私が説明した問題のいくつかはおそらく私自身の愚かさと無知の結果であるという事実にもかかわらず、64ビットアプリケーションの開発のメザニズムは少し複雑で混乱しているように思えます。 また、現時点では、Direct2DおよびDirectWriteテクノロジを使用してテキストを描画する方が適切であると思われます。



ご覧いただきありがとうございます! じゃあね!



All Articles