はじめまして、「らりばど」と申します。
会社の先輩からお祝いにいただいた「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/
回答は一言だけ。未確認なので見当違いかもしれませんが。
「関数定義が間違っています」
> 最後に、申し訳ありませんが以下の2箇所の掲示板にて同様の質問を
> 挙げさせていただいております。
断りを入れようが入れなかろうが同じです。
両方の管理人に断りを入れて、了承を得てからならば良いと思いますが。
それでも、両方に書き込みがあれば知っている人も「向こうで書いているだろうから、こちらで書く必要ないかな」と思ってしまいます。
普通に1箇所に書くよりレスポンスは遅くなりますよ。
# たくさん書けばよいというわけでないです
>管理者様、にしのさん、ALL
2箇所での発言についてご迷惑をお掛けしました。
申し訳ありませんでした。
>にしのさん
レスありがとうございます。
関数定義という点で見直してみましたがうまくいきません。
申し訳ありませんが、どの部分の関数か教えていただけないでしょうか。
私が間違っていたと思ったのは、
lpfnEnableEUDCの部分で、CとDelphiとTrueとFalseの値が
異なることで、直接値(Trueなら'1'、Falseなら'0')を
引数として渡せばいいのでは?
とやってみましたがダメでした。
私の視点は全然検討違いでしょうか?
ちょっと違います。
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)で処理していると思います。
>にしのさん
不足していたパラメータ「stdcall」を追加することで
問題なく動作するようになりました。
True,Falseもそのまま使えます。
本当にありがとうございました。
ツイート | ![]() |