【他でも動く】C言語/C++ で作った関数をHSPで動かす【DLL】

【他でも動く】C言語/C++ で作った関数をHSPで動かす【DLL】

HSPがGUIとか簡単に作れるけど速度遅い!
C/C++は拡張性めっちゃ高いしコンパイラだから早いけどプログラムを短時間で作れない!
というわけで、計算処理をCにまかせて他をHSP (本当はCでGUIできますけどここでは簡単に作れるようにするということ) でやればいいじゃない!ってことになります。
で、まず、HSPから利用できるようにするためには、コンパイルしてDLLを作成する必要があります。
ところが、ググるとHSP専用のDLLHPI (DLLの拡張子を変えただけ) の作成の仕方がよく出てきます。
それだとまさに拡張性がなくなってしまうので、C/C++でもHSPでも利用できるDLLでやろうと思います。
次に、それをHSPから利用できるようにするため、ヘッダファイルを作ります。
関数を作るうえで注意しなければいけないのは、HSPから直接変数を渡すことはできないため、変数を使うならポインタで渡さなければいけない点、それと、HSPとCでは配列変数のデータの格納の仕方が異なることに注意しなければなりません。
1.DLLの作り方
まず、main関数を取り除きます。
次に、
関数定義を

extern "C" __declspec(dllexport) [返り値の型] __stdcall [関数名]([引数いろいろ])~

とします。具体的に言うと、

double half(int p1)

とかなんとかだったら

extern "C" __declspec(dllexport) double __stdcall half(int p1)

という感じに。
あとはコンパイラでDLLを作成してください。(コンパイラによって作成方法が異なります。私はBorland C++ Compilerを使用しているので「bcc32 -WD ~~.cpp」)
2.ヘッダファイルの作り方
C/C++用であれば、__declspec(dllimport) で関数をプロトタイプ宣言のようにしてあげればおk (上記のような書き方でおk) 。コンパイル時に「~~.lib」ファイル (これも各自で作成。bcc32なら「implib ~~.lib ~~.dll」で作成) と一緒にコンパイルしてあげれば実行できます。
HSP用であれば、#uselibでDLLを指定し、#funcや#cfuncで命令・関数の定義を行えばおk。変数とかを渡すところに注意 (ヘルプ参照) 。
どちらの場合も、実行ファイル配布時はDLLも一緒にすることを忘れずに (当たり前のことだけど一応) 。
注意点1:変数はポインタで渡す
HSPだと普通に直接変数指定しちゃってますが、DLLでやるにはポインタで渡します。
C/C++なら変数の前に&をつければおk。
HSPならば、変数を指定するところをvarptr関数でポインタを取得して渡してください。変数を操作したときなどにアドレスが変わる可能性があるので、HSP上では関数の引数として直接varptr(変数)と指定しちゃったほうが良いでしょうたぶん。
注意点2:配列変数の仕様が違う
たとえば、2次元配列の変数があったとして、

Y↓X→
.    1 2 3
.    A B C
.    X Y Z

という風にデータを扱いたいとき (ここではわかりやすいように文字使っちゃってますが、実際にC・C++で文字/文字列使うとなるとやり方変わります) 、

HSPでは

1 2 3 A B C X Y Z

と格納するのですが、
C/C++だと

1 A X 2 B Y 3 C Z

という風に格納していきます。
このため、普通に配列変数を使っているとバグります。(1次元配列のみだったら問題ないのですが)
C/C++から利用するなら何もしなくて良いのですが、HSPから利用する場合のみ、ヘッダファイル内で処理しちゃうのもよいでしょう。その時は、配列変数を与える時、結果を代入してもらったときどっちも変換が必要なことを忘れずに。
まあこれらだけ気を付けていれば簡単にライブラリが作れるのではないでしょうか。
ではまたいつか。
↓クリック (投票) お願いします~


「【他でも動く】C言語/C++ で作った関数をHSPで動かす【DLL】」への2件のフィードバック

  1. 非常にありがたい記事です^^!
    作成するときに大いに参考にします。

コメントは受け付けていません。