- PR -

Delphi8にて動的DLLの呼び出し方法

投稿者投稿内容
灼熱
会議室デビュー日: 2004/03/04
投稿数: 13
お住まい・勤務地: 山口
投稿日時: 2004-03-05 09:06
間違ったところに書き込みをしたようでした。

Delphi8-VCLフォームアプリケーションで
作成しています。

TFunTest = function(CCC,DDD: ShortString):Boolean of object;

procedure TForm1.Button1Click(Sender: TObject);
var
LibHandle: THandle;
FunTest: TFunTest;
AAA:ShortString;
BBB:ShortString;
begin
AAA := 'AAA';
BBB := 'BBB';
LibHandle := LoadLibrary('Library1');
FunTest := GetProcAddress(LibHandle,'FunTest'); <==ここでエラー
FunTest(AAA,BBB);
FreeLibrary(LibHandle);
end;

のときに、'TFunTest'と'IntPtr'には互換性がありません」というエラーが
でます。Delphi8になり、
「Win32 では,○の例の変数は,すべて手続き型ポインタ(手続きまたは関数のアドレスを指すポインタ)です。.NET プラットフォームでは,手続き型はデリゲートとして実装されます。インスタンスオブジェクトのメソッドを参照する場合,語 of object を手続き型名に追加する必要があります。」
ということまで、理解(?)できたのですが、それからは、分かりません。
どうかよろしくお願い致します。
object
ぬし
会議室デビュー日: 2002/03/20
投稿数: 338
お住まい・勤務地: 香川県高松市
投稿日時: 2004-03-05 12:15
objectです。

コード:
 //FunTest := GetProcAddress(LibHandle,'FunTest'); <==ここでエラー
 @FunTest := Pointer(GetProcAddress(LibHandle,'FunTest'));// <==ここでエラー


上の様にすれば、コンパイルは通るのではないでしょうか?

コード:
FunTest: TFunTest;


はグローバルにする必要がある様ですね。
そうでないと、FunTestに対するデリゲートが破棄され、実行時例外が発生する場合がある様です。

もっと基本的な所で、質問です。
恐らく、VCLプラットフォームのメソッド呼出しを考えておられるんだと思いますが、
GetProcAddressで、インスタンスメソッドの指定は出来るのでしょうか?
この機能は、ボーランドが独自に提供しない限り出来ない様に私は思います。
#インスタンスメソッドには、当然インスタンスが必要です。
#ボーランドは「VCL」を「VCL.NET」に移行すれば、そういう機能は全く必要無いと考えているようです。
灼熱
会議室デビュー日: 2004/03/04
投稿数: 13
お住まい・勤務地: 山口
投稿日時: 2004-03-05 13:36
返信ありがとうございました。
おっしゃる通り、コンパイルは通りました。
が、実行後に、このDLLを呼び出したときに、
「オブジェクト参照がオブジェクトインスタンスに設定されていません。」
というエラーが出ました。

>>GetProcAddressで、インスタンスメソッドの指定は出来るのでしょうか?
>>この機能は、ボーランドが独自に提供しない限り出来ない様に私は思います。

このエラーは、上記の点(おっしゃられている点)が
関係しているのでしょうか?
とりあえず、動的にDLLを呼び出すことはできないようですので、
静的にDLLを呼び出すことにします。
(静的にDLLを呼び出すことはできましたので…。)
object
ぬし
会議室デビュー日: 2002/03/20
投稿数: 338
お住まい・勤務地: 香川県高松市
投稿日時: 2004-03-05 17:13
objectです。

>静的にDLLを呼び出すことにします。
>(静的にDLLを呼び出すことはできましたので…。)
という事であれば、

コード:

//TFunTest = function(CCC,DDD: ShortString): Boolean of object;
TFunTest = function(CCC,DDD: ShortString): Boolean; stdcall;



に変更し、後は「stdcall」等の呼出し規約を適宜変更すれば大丈夫ではないでしょうか?

それから、基本的には「LibHandle」、「FunTest」のチェックを行った方が良いと思います。
kiki
会議室デビュー日: 2004/03/05
投稿数: 2
投稿日時: 2004-03-05 17:49
Delphi今から勉強です。

BorConの資料とマニュアルによると、、、、
予めDelphiで定義していないAPIをCallする場合は、
実装の代わりに外部モジュールのコード呼び出しを宣言して、
DLLのハンドルを取得しアドレスを割り当てる必要があるそうです。

試していませんが、
.NETで Win32 API を呼び出すのと同じように変更する必要があるのでは。
資料に従うと、下記のようになるらしいです。

uses
 System.Runtime.InteropServices; //for DllImport

// DllImportを利用してレイトバインディングを行う
[DllImport('xxxxx.dll', CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'FunTest')]
var
UHandle: HMODULE;
CanFunTest: Boolean;
begin
UHandle := GetModuleHandle('xxxxx.dll');
if UHandle <> 0 then
// 実行時例外が発生しないように、APIを使用できるかどうか判定する
   CanFunTest := GetProcAddress(UHandle, 'FunTest') <> nil
else
CanFunTest := False;

if CanFunTest then
FunTest(AAA, BBB);

マニュアルは、
「Delphi8 for ..... 」-> 「CL for .NETへのアプリケーションの移植」
->「VCLアプリケーションをDelphi for .NETに移植する際の言語の問題」のページの
”ポインタ型の移行”の”手続きポインタ”(ページ上1/4辺り)
に説明と変換コード例が載っていました。

試した結果を教えてくれるとうれしいです。
CHN
ぬし
会議室デビュー日: 2002/03/07
投稿数: 382
投稿日時: 2004-03-05 18:02
こんいちは。

すいません
ちょっと、関係ないですが、
最近Delphi8に日本語版がでましたが、
ファイルの保存場所を日本語を使うとコンパイル
すらできないバグがありますよね。
これって、、、、、どうですかね??
日本語版ですよ!
英語版のときは、ま、いいかって感じで気にしませんでしたが。
ありえないバグですよね?
もうちょっと力を入れてほしいですね、Borland
自らDelphiを滅ぼすつもり???
_________________
灼熱
会議室デビュー日: 2004/03/04
投稿数: 13
お住まい・勤務地: 山口
投稿日時: 2004-03-05 18:46
「object様」
何度も返信ありがとうございます。
>>TFunTest = function(CCC,DDD: ShortString): Boolean; stdcall;
>>に変更し、後は「stdcall」等の呼出し規約を適宜変更すれば大丈夫ではないでしょうか?
教えていただいたようにしてみましたが、結果は以前と同じでした。
いったいなにが悪いのでしょうか?
いろいろ試してはみてますが、相変わらずです。
もう少し自分でも考えてみます。

>>それから、基本的には「LibHandle」、「FunTest」のチェックを行った方が良いと思います。
了解しました。


「kiki様」
返信ありがとうございます。
>>if UHandle <> 0 then
で、必ず値“0”が戻ってきます。
どこかに、ソースの足りない部分があるのでしょうか?
もう少し自分でも考えてみます。

「CHN様」
>>ファイルの保存場所を日本語を使うとコンパイル
>>すらできないバグがありますよね。
そ〜なんですか?初めて知りました。
>>もうちょっと力を入れてほしいですね、Borland
>>自らDelphiを滅ぼすつもり???
おっしゃる通りだと思います。
kiki
会議室デビュー日: 2004/03/05
投稿数: 2
投稿日時: 2004-03-05 19:37
しまった。
UHandle := GetModuleHandle('xxxxx.dll');
じゃなくて、
UHandle := GetModuleHandle('xxxxx');
と書いてある。
(VC++の例だと 'xxxxx.dll'だったのに???両方やってみてください。)

スキルアップ/キャリアアップ(JOB@IT)