Cからの移行、外字ロック制御が有効にできない

解決


らりばど  2002-03-04 13:54:52  No: 625  IP: [192.*.*.*]

はじめまして、「らりばど」と申します。

会社の先輩からお祝いにいただいた「Delphi4」を勉強しはじめました。
そして VC6 で作成したソースを Delphi4 に移行しているのですが、
原因がわからない現象が発生し質問させていただきます。

環境:Windows2000 + Delphi4

WinNT系OSから外字ファイルに対するロックを制御するコンソールアプ
リケーションプログラムを作成しています。
有効にしたり無効にしたりすることで、外字ファイルの置換を行なう
為です。

VC6 でコンパイルしたEXEでは問題なく動作するのですが、Delphi4
向けに作成し直したソースをコンパイルしたEXEの場合、"無効"に
することはできるのですが、一度"無効"にした状態から"有効"にする
ことができません。プログラム自体は、エラー処理が実行されるわけ
でもなく終了しています。
エラー処理の判断基準が間違っているのでしょうか。


※※※  C言語側のソース  ※※※※※※※※※※※※※※※※※※
typedef BOOL (WINAPI *ENABLEEUDC)(BOOL); 

ENABLEEUDC lpfnEnableEUDC;
HINSTANCE hDll;
BOOL bRet;

hDll = LoadLibrary("GDI32.DLL");
if (hDll == NULL){
  // エラー処理 //
}

lpfnEnableEUDC = (ENABLEEUDC)GetProcAddress(hDll, "EnableEUDC");
if (lpfnEnableEUDC == NULL) {
  // エラー処理 //
}

/* 外字使用の有効/無効 */
bRet = lpfnEnableEUDC(TRUE);    // 外字ロックを有効にする時 
bRet = lpfnEnableEUDC(FALSE);   // 外字ロックを無効にする時
if (bRet == FALSE) {
  // エラー処理 //
}
// 成功メッセージ表示 //

// 終了処理 //


※※※  Delphi側のソース  ※※※※※※※※※※※※※※※※※※
type ENABLEEUDC = function(hMode : Boolean) : BOOL;

var FarProc : TFarProc;
var lpfnEnableEUDC : ENABLEEUDC;
var hDll : Thandle;
var bRet : bool;

//モジュールのロード
hDll := LoadLibrary(PChar('GDI32.DLL'));
if hDll = 0 then
begin
  // エラー処理 //
end;

//モジュールからアドレス取得
FarProc :=GetProcAddress(hDll, 'EnableEUDC');
if FarProc = nil then
begin
  // エラー処理 //
end;

lpfnEnableEUDC := FarProc;

bRet := lpfnEnableEUDC(TRUE);    // 外字ロックを有効にする時
bRet := lpfnEnableEUDC(FALSE);   // 外字ロックを無効にする時
if bRet = FALSE then
begin
  // エラー処理 //
end;
// 成功メッセージ表示 //

// 終了処理 //

※※※  以上  ※※※※※※※※※※※※※※※※※※


最後に、申し訳ありませんが以下の2箇所の掲示板にて同様の質問を
挙げさせていただいております。

http://madia.world.coocan.jp/index_main.htm

http://member.nifty.ne.jp/h_kova/

編集 削除
にしの  2002-03-04 14:46:22  No: 626  IP: [192.*.*.*]

回答は一言だけ。未確認なので見当違いかもしれませんが。
「関数定義が間違っています」

> 最後に、申し訳ありませんが以下の2箇所の掲示板にて同様の質問を
> 挙げさせていただいております。

断りを入れようが入れなかろうが同じです。
両方の管理人に断りを入れて、了承を得てからならば良いと思いますが。
それでも、両方に書き込みがあれば知っている人も「向こうで書いているだろうから、こちらで書く必要ないかな」と思ってしまいます。
普通に1箇所に書くよりレスポンスは遅くなりますよ。
# たくさん書けばよいというわけでないです

編集 削除
らりばど  2002-03-04 21:09:35  No: 627  IP: [192.*.*.*]

>管理者様、にしのさん、ALL

2箇所での発言についてご迷惑をお掛けしました。
申し訳ありませんでした。

編集 削除
らりばど  2002-03-04 21:15:08  No: 628  IP: [192.*.*.*]

>にしのさん

レスありがとうございます。
関数定義という点で見直してみましたがうまくいきません。
申し訳ありませんが、どの部分の関数か教えていただけないでしょうか。

私が間違っていたと思ったのは、
lpfnEnableEUDCの部分で、CとDelphiとTrueとFalseの値が
異なることで、直接値(Trueなら'1'、Falseなら'0')を
引数として渡せばいいのでは?
とやってみましたがダメでした。

私の視点は全然検討違いでしょうか?

編集 削除
にしの  2002-03-05 00:04:42  No: 629  IP: [192.*.*.*]

ちょっと違います。
Cでの定義にある、WINAPIにあたるものが、Delphiにありません。
もし、Cの定義の、
typedef BOOL (WINAPI *ENABLEEUDC)(BOOL); 
が、
typedef BOOL (*ENABLEEUDC)(BOOL); 
ならば、Delphi側はこれであっています。

このあたりは、windows.pasなどのソースを見ると理解できるかもしれません。
ソースがあれば、ですが。
ヘルプで、「呼び出し規約」を参照してください。
C側の、WINAPIもマクロなので、VCのヘッダファイルをあさって見てください。
答えは見つかると思います。
APIを使う上で、結構重要な(=はまる)箇所です。
APIを使わずにVCLだけならば、呼び出し規約など気にしなくてよいですし。

True,Falseは、大抵の場合はうまくいくはずです。
昔は、True=1が災いして、2を指定したときにうまくいかないことがありましたが、今は内部では<>0(C的には!=0)で処理していると思います。

編集 削除
らりばど  2002-03-05 14:29:59  No: 630  IP: [192.*.*.*]

>にしのさん

不足していたパラメータ「stdcall」を追加することで
問題なく動作するようになりました。
True,Falseもそのまま使えます。

本当にありがとうございました。

編集 削除