喫茶XRAYトップページ

[スレッド全体
]

[7911] DLL内の関数のcdecl呼出規約返信 削除
2014/9/9 (火) 00:14:00 Mr.XRAY
とある場所で,cdecl というのを見かけましたので.ちょっと.
この cdecl は関数の呼出規約の 1 つです.
今回は DLL 内の関数の呼出しとなっています.

http://ja.wikipedia.org/wiki/%E5%91%BC%E5%87%BA%E8%A6%8F%E7%B4%84

C または C++ で作成した Linux 用の共有ライブラリを,
Kylix(カイリックス- 死語?), FreePascal で使用する際,
多くの場合,stdcall ではなく cdecl を使用します.
Linux の共有ライブラリの拡張子は so です.libXXXX.so.XXXX の形式です.

DLL 内の関数を cdecl 呼出規約で定義した場合,
DLL 内の関数を使用する側のプログラムも,当然 cdecl 呼出規約で
関数を定義します.

Windows の共有ライブラリ DLL では,上のリンクの記事のように,
stdcall を使用した方が無難です.
stdcall は Pascal の呼出規約と同じと考えて差し支えないと思います.
Windows では stdcall が事実上のデファクトスタンダードの呼出規約です.


呼出規約を cdecl にした場合のサンプルです.
基本的に,以下の記事のように,DLL 内の関数を使用するのに,
DLL を作成した言語は直接の関係はありません.
あるのは,作成した関数の引数の型や戻り値の扱い方等です.

現に,少し前に PDF の作成用の DLL を Visual Studio 2013 Express
で作成しています.

http://mrxray.on.coocan.jp/Delphi/Others/Usage_Win32API.htm


cdecl 呼出規約のDLL内の関数の使用例

implementation

{$R *.dfm}

type
  TQueryStatus = function(ID: Integer; var ResID: Integer): PWideChar; cdecl;

//-----------------------------------------------------------------------------
//  DLL内のcdecl呼出規約の関数の使用例
//
//  Windows 7 U64(SP1) + Delphi XE(UP1) Pro
//  DLLはWindows 2000 + Delphi 6で作成したもの
//
//  2014年09月08日 Mr.XRAY
//-----------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
  DLLPath     : String;
  DLLHandle   : Cardinal;
  QueryStatus : TQueryStatus;
  ID          : Integer;
  ResID       : Integer;
  Description : WideString;
begin
  DLLPath := 'cdecl_Test.dll';
  DLLHandle := LoadLibrary(PChar(DLLPath));

  if DLLHandle <> 0 then begin
    try
      @QueryStatus := GetProcAddress(DLLHandle, 'QueryStatus');
      if @QueryStatus <> nil then begin
        ID := 20;
        Description := QueryStatus(ID, ResID);
        ShowMessage(Description + '    ' + IntToStr(ResID));
      end;
    finally
      FreeLibrary(DLLHandle);
    end;
  end;
end;


使用した DLL のコード
DLL は Windows 2000 + Delphi 6 で作成


library cdecl_Test;

uses
  SysUtils,
  Classes;

function QueryStatus(AID: Integer; var ResID: Integer): PWideChar; cdecl;
var
  FID     : Integer;
  StrText : WideString;
begin
  FID     := AID;
  StrText := 'テストDLL関数';

  Result := PWideChar(StrText);
  ResID  := FID * 50;
end;

exports
QueryStatus;

begin
end.

プロジェクトのダウンロード (EXE 付き)
http://mrxray.on.coocan.jp/Delphi/zip/cdecl_dll_functionCall.zip

下図は,添付の EXE の実行結果です.


[7912] Re:DLL内の関数のcdecl呼出規約返信 削除
2014/9/9 (火) 00:53:59 Mr.XRAY
今度は,DLL を Windows 7 U64(SP1) + Delphi XE(UP1) Pro で作成し,
DLL を使用する EXE を Windows 7 U64(SP1) + Delphi 7 Pro で作成した場合です.
コードは全く上の時と同じです.もちろん実行結果も同じです.
DLL のファイルサイズがかなり大きくなっていますが...

Delphi 6 で作成した DLL のサイズ 139 KB
Delphi XE で作した DLL のサイズ  302 KB


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82