CDECL呼び出しで作られたDLLの実行

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
jacoby
記事: 106
登録日時: 2006年6月02日(金) 18:20

CDECL呼び出しで作られたDLLの実行

#1 投稿記事 by jacoby »

Cで作られたDLLを利用する時の「呼び出し形式」(CDECL)について教えてください。
stdcallでの呼び出しで作られたDLLは実行できるのですが、CDECL形式で作られたDLLの実行ができません。

テストとして二つの引数の値を足して返すCの関数のDLLを以下のように作りました。

DLLのヘッダファイル "DLL_Header.h"

コード: 全て選択


#define Export extern "C" __declspec(dllexport)
Export long __cdecl func_add( long a, long b );
DLLの関数実装部ファイル

コード: 全て選択


#include "DLL_Header.h"

// a + bの計算結果を返す。
Export long __cdecl func_add( long a, long b ){
 return a+b;
}
以上のCのプログラムを"BCC_DLL.dll"という名前でDLLにコンパイル。
(BCC 5.5/BCC Developer使用)


これを利用するAB側(v4.24)のプログラム

コード: 全て選択


Declare Function func_add CDECL Lib "BCC_DLL" ( a As Long, b As Long ) As Long

#prompt
Dim a As Long, b As Long
a=1
b=2
Print func_add( a, b )


ただしこれを実行するとABのプログラムがDLLの関数を「参照出来ない」、とエラーとなります。
(「stdcall」での呼び出しに変えると実行できます。)
AB(WinAPI)はデフォルトでstdcallとのことですがCDECL呼び出しを行っているケースもあります。
CDECLでの呼び出しには「Declare Function func_add CDECL Lib ~」というように関数名の後に
CDECLを入れるということなのでとりあえずそう書いてはいるのですが、今のところABからDLL関数を見つけられないようです。
CDECL呼び出しについて、お知りの方がおられましたら教えてください。

(AB4.24
BCC 5.5/BCC Developer)
たかせ
記事: 215
登録日時: 2006年2月05日(日) 17:10
お住まい: 東京都

Re: CDECL呼び出しで作られたDLLの実行

#2 投稿記事 by たかせ »

私も試してみました。
プログラムの内容は提示されているものと異なっていますが、おっしゃるとおりCDECL形式で作られたDLLの実行ができませんでした。
ちなみにC/C++でつくられたプログラムでは問題なく実行できました。
ソースコードは特に問題ないと思います。
私も「なぜそうなるのか」がよくわかりませんが、とりあえず特に理由がなければstdcall呼び出しでよいと思いますが。
いかがでしょうか?
jacoby
記事: 106
登録日時: 2006年6月02日(金) 18:20

Re: CDECL呼び出しで作られたDLLの実行

#3 投稿記事 by jacoby »

たかせさん、返信ありがとうございます。テストしていただいて恐縮です。
元々この問題に突き当たったのは、黒蝿さんが公開されているAB用のDXライブラリの「DxLibDll」を使わせてもらっていて、非公開関数で「DxLibDll」に収録されていないものがあったので("SetUserWindow()")、そこで自分で使う最低限の命令だけを選んでDXライブラリをDLL化出来ないかと思っていた時だったのですが、そこでこのCDECL呼び出しの問題に出会うこととなってしまいました。
 当初は全てDLLをstdcallで作成していたのですが、DXライブラリの定数や関数の定義は膨大なのでDxLibDllのパッケージに含まれている「DxLib.sbp」というヘッダーファイルだけは借用させてもらおうと思い(使わない関数はコメントアウトするとして)、それをインクルードして実行すると、上手く動いたように思えた次の瞬間、アクセス違反のエラー。エラーの出方がちょっと独特だったので、調べるとDLL呼び出し時のスタックに関わるエラーの様で、「DxLib.sbp」ヘッダファイルの中身を改めて調べると全てCDECL方式での呼び出しになっていました。
 もちろんヘッダーも書き直し、全てstdcallでの呼び出しに変えることによって動作させることも方法だと思うのですが、現状では出来ればCDECLで呼び出せればと思っています。
(経緯が長くなってしまってすみません。ABで作成したウインドウをDXライブラリでもそのまま使いたいという単純な所から、流れ流れてこの質問に至りました。)

以降、色々調べてみたのですが、「DxLib.sbp」ヘッダファイルでも書かれているようにAB側のCDECL呼び出し記述自体はあのままで間違っていないと思います。

問題はCの関数がどのような名前でDLL化されているのか、ということじゃないかと。(この時点でABの質問板ではあまりふさわしくない質問になってしまっているのですが)
 (ただし、たかせさんのテストで、C/C++のプログラムからは問題なく実行出来たということを考えれば、それも違うのかなとも思えますよね。)

sinryowさんの「http://ab.sinryow.net/topic04.php」の解説ペー ... かして「Visual C++」か「BCC Developer/BCC5.5」かによって関数の名前が変わってくるのかな、、と。
DLLのコンパイルが通る以上BCC Developerでも出来たら、と思っていまが、あと少しだけ調べてみて、最終的にはVC++でチェックしたいと思っています。

たかせさん、改めて、テストしていただきありがとうございました。また何かありましたらよろしくお願いします。
返信する