C#のソースやモジュールを、秀丸用のC++/CLIの.dllへとスタティックにリンクする

  • 概要

    マネージド.dllは、Windowsのみならず、Androidでもものすごい勢いで利用されています。

    このため、開発者は、「ネイティブな上、理解しずらく、特定のCPUでしか動作しない、C++ライブラリ」の作成を敬遠し、
    複数のプラットフォーム、CPUビット数に関係なく動作することが期待できるマネージドdll、
    とりわけソースコードが理解しやすいC#でのdll作成を好むようになってきます。

    よって、マネージドなdllを秀丸で作るC++の.dllに直接スタティックリンクしてしまう、といった手段を知っておくと便利です。

  • C++/CLIとC#の混在プロジェクト

    WindowsのC++には、C++/CLIという混成アセンブリを作成出来る言語が存在するため、
    C++プロジェクトとC#プロジェクトを一緒のソリューションの中に入れ、
    そのまま1つの.dllとしてコンパイルしてしまうことが可能となっています。

  • C#側とC++/CLI側の.NETのバージョンは一致させること

    C#側とC++/CLI側の.NETのバージョンは一致させる必要があります。
    例えば、.NET Framework 4.5.2であれば、両方ともそのバージョンを指定します。

  • C#側はANYCPUのModuleでのコンパイル

    C#側は「ANYCPU」でコンパイルします。
    そして、「Module」の指定をします。
    Moduleの指定はGUI上ではできません、「.vcxproj」ファイルを直接編集します。

    「Module」という指定をしておくことで、C#側はコンパイル時に、
    「.dll」ではなく、「.netmodule」という拡張子のファイルとなります。

  • C++側はC#側のプロジェクトを参照しておく

    C++/CLI側の参照には、C#側の「プロジェクト」そのものを参照で追加しておきましょう。

  • C++/CLI側は、「リンカー」の「追加依存のファイル」にC#側で作られる「.netmodule」を追加指定しておく

    C++/CLI上でC#のクラスを利用した場合、当然その実態がC++側に存在しないことになりますので、
    静的リンクの対象として、.netmoduleを指定します。

  • 1つの.dllとなる

    以上で、C++/CLIとC#がソース中に混ざっていても、1つの.dllにコンパイル出来ます。

  • このテクニックが使われているソースコードの代表例

    HmHtmlPreviewのソースコードが代表例となるでしょう。

  • 備考

    C#のdynamic型はC++/CLIには存在していません。
    とりわけC#側のメソッドの返り値がdynamic型である場合には、C++/CLI側で対処しようとはせず、
    C#側で一旦「dynamic型が無いメソッドの形へとラップ」し、
    そのラップしたメソッドをC++/CLI側から利用するようにしてください。