MSYSとMinGWでGSLをビルドしてVisual C++から使う
出典: Wikimura
数値計算ライブラリGSLの古いバージョン(1.10)にバグがあったため、最新版を入手することにした。 GSLはWindowsでも動くが、VisualStudioでビルドするには工夫が必要らしい。 1.8や1.10についてはVisualStudioのプロジェクトやバイナリが配布されているが、どうせなら最新版を常に手に入れられるようにしたい。そこで、GSLのビルド方法について調べた。
この方法では呼び出し規約の違いで不具合が生じるようです。現在調査中...
Visual C++でビルドすることで解決しました。方法をGSLをVisualC++でビルドする に書きました。
目次 |
注意! このページの内容は間違っています。正しくは「GSLをVisualC++でビルドする」の方を参照してください
このページの通りにやるとビルドはできますが、gccとcl(Visual C++のコンパイラ)で呼び出し規約に違いがあるため、ランタイムエラーを起こします。
最初からVisual C++を使ってビルドすれば解決します。GSLをVisualC++でビルドするを参照してください。
エラーが起こる例:
#include <gsl/gsl_vector.h>
#include <stdio.h>
int main( void)
{
double array[3] = { 1, 2, 3};
gsl_vector_view view = gsl_vector_view_array( array, 3);
return 0;
}
エラーメッセージ:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
必要なものは
詳しくは[6][7]参照。MinGWをインストール後、MSYSをインストールし、環境変数を設定する。
Unix模擬環境(Cygwin or MSYS)
GSLはUnix向けのライブラリらしく、UNIXが提供する機能(システムコール?)を必要とするらしい。 そのため、Windows上でUnix環境を模擬するソフトウェアが必要となる。 これにはCygwinかMSYSを用いることができるらしい。
始めはCygwinを使おうと考えたが、Cygwinではホスト(コンパイルしたものを実行する側)がi686-pc-cygwinのgccに都合よく設定されているので、結構面倒なことが分かった。
ここは素直にMSYSを使うことにした。 MSYSのインストールについては[7]参照。
MinGW
gccのWindows移植版で、直接Windows上で動くプログラムを作るためのツールチェインとのこと。 (Cygwinなどのgccでは、そのままではWindows上で動くことができず、cygwin.dllが必要とか言われてしまう)
ビルドする
MSYSのコンソールを立ち上げ、GSLのソースディレクトリへ移動する。 (Cygwinと異なり、ドライブはルート直下にマウントされている)
./configure --prefix インストール先 make make check make install
設定項目は configureで -h オプションを使えば調べられる。prefixでインストール先を指定する以外、特にやることはなかった。 何事もなくビルドでき、checkも問題なく実行できた。 特に指定しなければ、静的ライブラリと動的ライブラリの両方が生成される。
1.13では、前に書いたgsl-1.10での「 subrow/subcolumnのバグ」は解決されていた。
Visual Studioからの利用方法
ビルドしたGSLをVisual Studio(というかC++)から利用するには、以下の設定を行う。 GSL_DirはGSLをインストールしたディレクトリ。configure時に--prefixオプションで指定した場所。
Visual Studio側の設定: 全てのプロジェクトに適用されるので便利(個別のプロジェクトで設定することもできる)
- ツール -> オプション -> プロジェクトおよびソリューション -> VC++ディレクトリ
- インクルードファイル: (GSL_Dir)/include
- ライブラリファイル: (GSL_Dir)/lib
- 実行可能ファイル: (GSL_Dir)/bin -> デバッグ時にDLLが探せるようになる
個別プロジェクトでの設定: Visual Studio側でディレクトリ設定がされていない場合、こちらで設定する。
- DLLで利用する場合:
- 構成プロパティ
- リンカ -> 入力 -> 追加の依存ファイル: libgsl.dll.a libgslcblas.dll.a
- C/C++ -> プリプロセッサ -> プリプロセッサの定義: (既存のシンボル定義);GSL_DLL(区切り文字としてセミコロンを使う)
- 構成プロパティ
- 静的ライブラリで使用する場合:
- 構成プロパティ
- リンカ -> 入力 -> 追加の依存ファイル: libgsl.a libgslcblas.a
- 構成プロパティ
うまくいかない?
MinGWでコンパイルすれば呼び出し規約(calling convention)がVisualStudioに合わせてもらえるものと思い込んでいたが...違うらしい。 gsl_vector_view_array関数をある関数内で実行したところ、関数から抜け出す際に、スタックがおかしいと怒られるという現象に遭遇してしまった。 非常に恥ずかしいミス。エラーメッセージは以下の通り。
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
[1]に以下のような気になる記述があった。
Visual C++を利用する理由: 構築したライブラリをVisual C++から利用するためです. Windows上で開発をする以上,準公式のVisual C++で行うのが好ましいと言えます. また,MinGWのdllwrapで構築されるインポートライブラリは Visual C++のものと互換性が無いようです.
更に、
以上の事情から,このページで作ったDLLはVisual Basicその他から利用することは出来ないと思われます.この場合はVisual C++で__stdcallを利用したラッパーライブラリを書くなどして対処してください.著者個人の見解では「実装上の問題が山積している状況でVBなど使うな」ということになるのですが.
とのこと。ライブラリやDLLが目の前に現れたからといって、そのまま使えるとは限らないということらしい。(昔H8でHEWのライブラリをGCCから使ってやろうとして痛い目にあったことがあるのに、またやってしまった
現在調査中。

