CLIP STUDIO PAINTのプラグインをC#で書きたい!(1)

あすかです。

我ながら言うのもあれですが、今回はちょっと狂気のある内容です。
もちろん、本当はやってはいけないことです。
本記事の内容を読んで作ったものは、インターネット上には公開せず、個人としての利用にとどめてください。

概要

今回は、グラフィックソフト「CLIP STUDIO PAINT」のプラグインを、C#で作ってしまおうというおはなしです。
(※自作プラグインの適用は、CLIP STUDIO PAINT EXのみの機能です

f:id:kmynews:20170723120440p:plain

CLIP STUDIO PAINT(以下クリスタ)の詳細は別のサイトに委ねるとして、「漫画やイラストを制作するためのグラフィックツール」くらいの認識でOKです。
そのクリスタは、プラグインを作って機能拡張することができます。
そのSDKも公開されていますよー!

www.clip-studio.com

でも、SDKC++のやつしかないです。C++以外でプラグインを開発する方法は用意されていないです。
そもそもグラフィックツールって、画像処理を何回もしますから、当然重い処理が何度も入ってきます。C++くらい高速でないと無理です。無理ですよね。

無理なのはわかってるんですが、いっぺんC#で作ってみたい!ってことで作ってみます。

まずサンプルプロジェクトのビルドから始めよう

まず、SDKを準備します。
SDKMFCを使うので、VSにMFC入ってない時はインスコします。

FilterPlugin\ProjectWinフォルダにslnが入っていますので、これをVSで開きます。
すると「HSV」というプロジェクトが出てきますね。
「x64」の「Release」に変更してから、これをビルドすればOKです。
(ビルドツールを最新のものにするか聞かれた時は、最新のものを選んでもいいです)

ビルドしたものは、

f:id:kmynews:20170723120750p:plain

FilterPlugin\OutputWin\FilterPlugin\HSV\Release\x64に出力されます。
出力されたファイルのうち、拡張子cpmになっているものを、ドキュメントのCELSYS\CLIPStudioModule\Plugin\PAINTにコピーします。

f:id:kmynews:20170723121046p:plain

これでクリスタを起動すると、フィルダーメニューになんか項目増えてます。

f:id:kmynews:20170723121323p:plain

これを選択して、ダイアログいじってみます。

f:id:kmynews:20170723121412p:plain

プレビューがうまく動いてれば成功です。

クリスタからマネージドコードを呼び出したい!

そもそもマネージドコードって?

詳しくは他のサイトに委ねますが、C++で普通にDLLを作っても、そのDLLから.NETの機能を呼び出すことはできません。
なぜでしょうか?それは、Windows.NET Frameworkの基盤が違うからです。

Windowsアプリは、Intel CPUの命令やWin32APIを呼び出して動きます。
それに対して.NET Frameworkアプリは、CLIという基盤の命令を呼び出すことで動きます。

gccなどのC言語コンパイラは、Intel CPU互換の命令を吐き出します。
CLIで動作するプログラムを作るC#とかのコンパイラは、CLI上で動作する、CILという中間言語を吐き出します。
WindowsでビルドしたASP.NET Coreのdllが、Linuxdotnetで動いちゃうのは、これが関係してますね。

マネージドコードとは、すなわちCLI上で動作するコードをさしています。
それに対して、アンマネージドコードとは、CLI上で動作しないコードをさします。

ていうか、C#で書いたものは、C#コンパイラがCILを吐く以上マネージドです。

アンマネージドコードからマネージドコードを呼び出す必要がある

CLIP STUDIO PAINTはマネージドコードであるかというと、全然そうではないです。
そもそもクリスタはOpenGLを使用する、WindowsMac上で動作するクロスプラットフォームアプリです。Xamarinを使っている場合ならともかく、.NETを使っている痕跡がないです。

そして、プラグインSDKでも、マネージドコードを使うことはできません。

SDKのプロジェクト設定では、こうなっています。

f:id:kmynews:20170723122835p:plain

C++のDLLからマネージドコードを呼び出すためには、プロジェクトの設定がこうなっている必要があります。

f:id:kmynews:20170723122805p:plain

マネージドコード、使えないですね。
ということで、SDKからマネージドコードが使えるよう、プロジェクトの設定を変更してしまいます。

また、マネージドコードを使う設定にすると、他の設定と競合してコンパイルエラーになりますので、他の設定も適当に変更します。

f:id:kmynews:20170723123147p:plain
f:id:kmynews:20170723123218p:plain

微妙な動作が変わってしまうかもしれないですが、今回は実験的な内容なのでこのままやってしまいます。

C++のアンマネージドDLLからC#のマネージドなクラスとメソッドを呼び出す

HSVHelperというC#.NET Framework DLLを吐くプロジェクトを作って、このようなコードを書いてみます。

Win32APIのメッセージボックスを表示するコードです。
そして、このDLLをビルドします。

ビルドしてできたDLLを、サンプルプロジェクトの参照に追加します。

f:id:kmynews:20170723123606p:plain

「参照」ボタンを押してDLLを選択すると、リストに出てきます。この状態でOKを押します。

次に、サンプルプロジェクトのPHSVMain.cppの30行目あたり(structの定義が終わったあたり)に、こんなコードを追加します。

(ちなみにこのコードは、マネージドコードとアンマネージドコードのブリッジ - マイクロソフト系技術情報 WikiにあったBridgeDLL.cppがもとになっています)

そして、このメソッドの呼出を、TriglavPluginCall関数の最初にある「プラグインの初期化」コメントの前に追加します。

これで、C#のプログラムを呼び出すクリスタプラグインの出来上がりです。

ビルドしてみる

これをビルドすると、HSVHelper.cpmのほかにもう1つ、HSVHelper.dllが出力されます。
CPMはさっきと同じところにコピーでOKですが、DLLのほうは、下に書いているディレクトリにコピーします。

C:\Program Files\CELSYS\CLIP STUDIO 1.5\CLIP STUDIO PAINT

クリスタ起動時にメッセージボックスが表示されれば成功です。

f:id:kmynews:20170723124120p:plain

まとめ

今回はクリスタのプラグインからC#のコードを呼んでしまいました。
次回は、C#のコードから、クリスタプラグイン用に提供された関数を使う方法を考えてみます。

kmycode.hatenablog.jp