ホーム ] PC技術/システム技術 ] VB.NETプログラミング ] VB.NETコンポーネント ] VC++コンポーネント ] 共通事項 ] インフォメーション ]

上へ
C++ネイティブDLL
試作第1号
試作第2号

C++コンポーネント

C++ネイティブDLL

最終更新日:2007/03/26  修正

●概要

 VB.NETでの高速化は一通り行ってきた。そろそろネタも底を突き始めたし、いよいよ、我がポリシーを変更し、C++の高速性を確認したくなった。C やC++は全く素人なので、勉強しながら進めて行く。この記事は、筆者の記録と思って貰えれば良い。但し、ここは、VBより更に眉唾になるのでご注意あれ。

●VC++

 VC++のマネージコードは、共通ランタイム上で動く(つまり中間言語)ので、VBやC#と実行速度は同じとなる。そう言う意味では、VC++でマネージコードを開発するのは、徒に時間を浪費することになるのでやめた方が良いと筆者は思う。

 I/Oが介在したり、人が介在する処理では、もともと、VBやC#によるマネージコードで十分対応できる。

●ネイティブとは?

 釈迦に説法であるが、ここで言うネイティブとは、X86機械語に直接落ちる実行コードのことを言う。VC++のマネージコードでは、中間言語に落ち、実行時にX86ネイティブになるが、バリバリのネイティブではなく、共通ランタイム上のコードであり、速度はVBやC#と同じとなる。VC.NETコンパイラでは、指定すれば、C++ネイティブコードを生成できるのである。

●高速化方針

 高速化すべき部分は、

  • メモリ上の処理である。
  • 大量のデータである。
  • 科学演算の固まりである。

と言う条件の部分となる。この部分を、C++ネイティブコード(アンマネージコード)で動かす。掻い摘んで言えば、演算のカーネル部分のみをC++ネイティブにすることになる。下図参照。

○処理時間の把握

 画像処理は、おおむね、

  1. メモリ上のビットマップから画素のバイト配列を取り出す。

  2. 必要なら、それを輝度にしたり、HSLにする。

  3. 必要なら、画像の周囲を拡張する。

  4. カーネル処理を行う。空間フィルタなど。

  5. 結果を配列に戻す。

  6. その配列をビットマップに戻す。

となる。

○バイト配列の取り出しと戻し時間

 計測すると下図のようになった。

 マーシャル転送時間は空間フィルタ処理時間に比べ、十分に小さいので、これを短縮しても効果はない。従って、バイト配列の確保と戻しはVBによるマーシャル転送で十分である。 

○領域拡張時間

 念のため実測した。下図のように、VBでも十分に短い時間となっている。

 

 以上のように、結局、リストの2が現状不明であるが、4のカーネル処理がやはり、DLL化対象となる。

●形式

 C++の関数をVBで利用できないといけないので、ダイナミック・リンク・ライブラリ(DLL)とする。こうすれば、C++で作成したDLLを、VBは実行時に参照できるので効率が良い。今回は、科学演算のみを対象にしたので、MFCも使わない素のC++となる。

●何をするのか?

 以下の二つが重要ポイントとなる。

  1. VC++にて、C++ネイティブのDLLを開発する。

  2. 上記のDLLをVBから実行時に参照できるようにする。

である。また、処理対象のデータは、VBで準備し、C++へは参照で引き渡し、C++でVBが準備した配列に結果を戻すような方式とする。これで、C++ではメモリ確保、解放処理が不要になる。

C++ネイティブDLLの開発

 市販の参考書には殆ど載っていなく、MSDNにてサンプルを見つけ、それを突破口にして開始できた。C、C++については、必要に応じて習得して行く方式とする。筆者としては、DLLができ、それをVBで使えれば、途中経過やスマートさは気にしない。

VBから参照

 できたC++のDLLを、VBから参照でき、実行時にリンクできるようにしないといけない。

配列の参照引き渡し

 次に、VBで準備した配列を渡したり、VBで準備した結果用の配列に、DLLが直接アクセスできるようにする。