2011/04/06

Visual Studio 2005でCrypto++ライブラリを使ってみる

手元のVisual Studio 2005はVB2005を使って、以前働いていた職場でプログラムを作る他はもっぱら自分の遊びようでしたが、今回はひさしぶりにVC++2005を使ってみる事にしました。

いまどきVC#じゃなくて、VC++を使ったのはIPropertySetStorageを使うプログラミングをするためにC#を使うのは大変でオーバーヘッドが大きくメリットがなかったからです。

IPropertySetStorageの使い方はいろいろ資料があるので、今回はそれと一緒に組み合せたCrypto++ライブラリの使い方についてメモを残しておきます。

Visual C++ 2005と組み合せる方法

www.cryptopp.com には、VC++との組み合せについて参考になるドキュメントはみつかりませんでした。

そこでGoogleでいくつか検索して参考にしたのは mogproject.blogspot.com の「Crypto++ 5.6.1のビルド」でした。

入手できるcryptopp561.zipを展開したディレクトリに含まれているslnファイルをVS2005から開きました。

この全体をDebug用とRelease用の2つのタイプに分けてビルドした後は、ひとまず閉じて、自分のプロジェクトファイルを開き直します。

使い方 - cryptopp.dll OR cryptlib.lib

どちらのファイルを使うにしても、ヘッダーファイルが含まれている、アーカイブを展開したフォルダのトップを「追加のインクルードディレクトリ」に含めておきます。

DLLを使う場合には、リンカオプションでDLLを含むディレクトリへのパスを通しておき、"dll.h"をインクルードするだけで直接 cryptopp.dll ファイルの名前を指定する必要はありません。

cryptlib.libを使う場合には、「追加の依存ファイル」に"cryptlib.lib"を含めておきます。

基本的にはこれだけだったのですが、デフォルトの設定で動かしていると次のような問題が発生しました。

自分のプロジェクトからCrypto++を使う時の問題

ビルドしたところ、DLLはうまく作れたけれど、LIBファイルとのリンクには失敗したという事が起こりました。

遭遇したエラーメッセージ

1>msvcprt.lib(MSVCP80.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) は既に cryptlib.lib(iterhash.obj) で定義されています。
1>msvcprt.lib(MSVCP80.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(char const *)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z) は既に cryptlib.lib(iterhash.obj) で定義されています。
1>LINK : warning LNK4098: defaultlib 'LIBCMT' は他のライブラリの使用と競合しています。/NODEFAULTLIB:library を使用してください。
1>C:\Users\yasu\Documents\Visual Studio 2005\Projects\TestCryptoPP\Release\TestCryptoPP.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。

これは「ランタイムライブラリ」の設定で「マルチスレッドDLLl(/MD)」が選択されていた事が原因です。

リンクする対象がDLLかスタティックライブラリかによって、オプションを変更しなきゃいけないのは理解できますが、どこを変更すれば良いのかは調べるのに時間がかかりました。

/MD, /MD等のメニュー

ランタイムライブラリ切り替えダイアログ

DLL v.s. スタティックライブラリ

簡単な文字列のSHA1 Digestを計算して、表示するアプリケーションを作成して比較しました。

DLLの場合は、DLLファイルが1.2MB程度で、オブジェクトコードは7KBほど。

スタティックライブラリの場合は、オブジェクトコードは88KBほど。

とりあえず自分の用途では、スタティックライブラリの方が扱いは楽かなぁと感じています。

Crypto++を扱う上でのリファレンス、マニュアル等

Googleなんかで検索すると、Crypto++のドキュメントがなさすぎるという記述を目にします。

確かにドキュメントやチュートリアルは少なくて、基本的な操作を知っている既にプログラマな人以外お断り的な雰囲気は感じます。

ただ、どういう風にメソッドやクラスを使えばいいのかというと、サンプルが付いてくるので、cryptestの中を除くとだいたい必要そうな情報はあるように思いました。

ちゃんと使っているわけじゃないので、なんともいえないですが、典型的な操作についてはテスト用のコードを追えばなんとかなりそうな気がします。

0 件のコメント: