(前回やるといっておいて、全くやっていませんでした。。。)
今回SWIGについての説明をします。
SWIGとは
てな感じで、C/C++のコードを他の言語でも使用できるというすぐれもの。SWIG (Simplified Wrapper and Interface Generator) は、 C/C++ で書かれたプログラムやライブラリを、Tcl/Tk、Perl、Python、Ruby、PHP、Lua などのスクリプト言語や、Java、C#、Scheme、Ocaml などの言語に接続するためのオープンソースのツールである。 (wikipediaより)
Perl/Python版DxLibもこれで実装しています。
今回はWindowsでPerl/Python/Java/C#で使用する方法を
例にとって説明していきます。
■環境準備
必要なもの
・VS or GCC (今回はVC2008を使用して説明)
・swigwin
・使用したいC/C++ソースコード
・各言語
VSは2008でも2010でも大丈夫です
2012は触ったことがないので不明。
swigは、ここからダウンロードしてください
アンケートに適当に答えてダウンロードしてください。
各言語(今回はPerl/Python/Java/C#)は各自取ってきてください。
また、swigwinをDLしたら
「swig.exe」があるパスをシステム環境変数に追加して
コマンドプロンプト上でswig のコマンドが打てるようにしてください。
また、今回はテスト用にC/C++のソースも添付しておくので
そちらを使用して実施します。
■手順
以下の流れで作成します。
・VS環境準備
・C++ソースの用意 (添付ファイル参照)
・xxx.iファイルの用意 (自分で作成)
・xxx.cxxの用意 (swigで作成)
・各言語のラッパーの用意 (swigで作成)
・dllの作成(VSで作成)
1.VS環境
VS環境は使用したことがある人ならわかると思いますが
プロジェクト作成→コンソール→空のプロジェクトで作成してください。
2.C++ソース
自作でも構いません。今回は添付ファイルを例にとります。
ファイルをVSに読み込ませておいてください。
3.iファイル
cxxファイルを作成するための情報を記入します。
iファイルは以下のように記入します。
%module モジュール名
%{
include ヘッダファイル名
%}
関数の列挙(または.hファイル)
#defineの定義など
今回はこんな感じ。
%module SwigTest
%{
#include "Output.h"
#include "TestClass.h"
%}
%include "Output.h"
%include "TestClass.h"
#define DEF 5
4.cxxファイル/ラッパーファイル
コマンドプロンプトを立ち上げ
先ほど作成した、SwigTest.iのあるフォルダまで移動します。
そこで、以下を入力します。
-perlはそれぞれ以下に変えてください。
Perl→-perl
Python→-python
Java→-java
C#→-csharp
です。
実施すると以下のファイルができたと思います。
・SwigTest_wrap.cxx (VSでdllを作成するために必要 cxx→c++用のファイルのこと)
・各言語用のモジュール (実際に各言語で使用するときに必要。ラッパーが書いてある。)
5.dllの作成
まず、VSを立ち上げ
C++コードが記入されたファイル(添付ファイル)とSwigTest_wrap.cxxを
追加します。
次にプロパティページから
・構成をReleaseに変更
・構成プロパティ→全般→構成の種類を「ダイナミックライブラリ」へ
・コード生成→ランタイムライブラリ→「マルチスレッド」へ
・リンカ→出力ファイル→「SwigTest.dll」へ(Pythonは「_SwigTest.pyd」)
・C/C++→追加のインクルードディレクトリ
Perl→「C:\Perl\lib\CORE」
Python→「C:/Python27/include」(or Python30)
Java→「C:\Program Files\Java\jdk1.7.0_10\include;C:\Program Files\Java\jdk1.7.0_10\include\win32;C:\Program Files\Java\jdk1.7.0_10\include\win32\bridge;」
・リンカ→追加の依存ファイル
Perl→「C:\Perl\lib\CORE\perl514.lib」(各バージョン.lib)
以上が完了したらビルドを実施して、dll(またはpyd)ファイルを作成します。
これで完了です。
後は実際に使ってみるだけです。
C#
SwigTest.cs、SwigTestPINVOKE.cs、TestClass.csを読み込んで
ビルドを実施。dllを「exe」があるフォルダと同じ階層に置く
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TestClass test = new TestClass();
test.SetNo(10); // 10をセット
test.GetNo(); // 10を取り出す
test.public_no = 5; // public変数にアクセス可能
SwigTest.DEF.ToString(); // defineの取得も可能
SwigTest.print(); // Test!!
}
}
}
SwigTest.java、SwigTestConstants.java、SwigTestJNI.java、
TestClass.javaを読み込んでdllを同じ階層に置く
public class Main {
static {
try {
System.loadLibrary("SwigTest");
} catch (UnsatisfiedLinkError e) {
System.err.println("ファイルが読み込めません" + e);
System.exit(1);
}
}
public static void main(String[] args) {
TestClass test = new TestClass();
test.SetNo(10);
test.GetNo();
test.setPublic_no(3); // public変数もゲッターセッターが用意される 変数への直接アクセスは不可
test.getPublic_no();
System.out.println(SwigTest.DEF);
SwigTest.print();
}
}
というわけで、他の言語でもC++コードを利用したいという方は
使ってみてはいかがでしょう。