5

私のアプリケーションは、外部DLLからさまざまな関数やプロシージャを呼び出す機能を提供する必要があります。したがって、パラメータの数とそのタイプはわかりません。これを行うにはどうすればよいですか?

もっと説明させてください。私のアプリケーションはRADツールであり、独自のスクリプトと構文があります...ユーザーが任意のdllファイルを使用して必要な関数またはプロシージャを呼び出せるようにしたいです。参照するタイプ( )がわからないため、dll(LoadLibraryおよび)を呼び出す簡単な方法を使用できません。GetProcAddressGetProcAddressvar Proc:procedure (A:??;B:??;...)

4

4 に答える 4

5

ZGameEditorプロジェクトのスクリプト機能にDelphi実装があり、以下のファイルで「TExpExternalFuncCall.Execute」を検索します。

http://code.google.com/p/zgameeditor/source/browse/trunk/ZExpressions.pas

Windows(x86およびx64)、Linux、Android(ARM)、およびOS X(x86)でテストされ、動作しています。stdcallおよびcdeclの呼び出し規約を処理します。

しかし、libFFIはおそらく私の実装よりもはるかに一般的であるため、そのアプローチをお勧めします。

于 2011-03-19T13:08:08.673 に答える
4

これは私のマシンで動作する簡単な例ですが、私はこのテーマの専門家ではありません。

procedure TForm4.Button1Click(Sender: TObject);
var
  hmod: HMODULE;
  paddr: pointer;         
  c1, c2, ret: cardinal;
begin
  c1 := 400; //frequency
  c2 := 2000; // duration

  hmod := LoadLibrary('kernel32'); // Of course, the name of the DLL is taken from the script
  if hmod <> 0 then
    try
      paddr := GetProcAddress(hmod, 'Beep'); // ...as is the name of the exported function
      if paddr <> nil then
      begin
        // The script is told that this function requires two cardinals as
        // arguments. Let's call them c1 and c2. We will assume stdcall
        // calling convention. We will assume a 32-bit return value; this
        // we will store in ret.
        asm
          push c2
          push c1
          call [paddr]
          mov ret, eax
        end;
      end;
    finally
      FreeLibrary(hmod);
    end;
end;
于 2011-03-18T22:13:11.610 に答える
3

あなたが説明しているものは、Foreign Function Interface(FFI)として知られており、心の弱い人向けではありません。

独自のFFIを最初から開発することはお勧めしません。FFIの非常に一般的な選択はlibffiです。

libffiのウィキペディアページには、libffiのユーザーとして次のプロジェクトがリストされています。

Python、Dalvik、F-Script、PyPy、PyObjC、RubyCocoa、JRuby、Rubinius、MacRuby、gcj、GNU Smalltalk、IcedTea、Cycript、Pawn、Squeak、Java Native Access、PLTスキーム、Embeddable Common Lisp、Mozilla。

私は個人的に、Python /ctypesインターフェイスを介してDelphiDLLへのlibffiを広範囲に使用していますが、ありがたいことに、Python/ctypesはそれを非常に高いレベルでラップしています。

あなたが説明するルートを出発する場合は、libffiの使用を強く検討します。そのルートを使用する場合は、C / asmで記述されているため、Delphiから使用できるようにするためにいくつかの作業を行う必要があります。

于 2011-03-18T22:09:12.333 に答える
3

デビッドHが言うように、FFIについては、気の弱い人にはほとんど向いていません。

ただし、libFFI(ctypes)が特定の構文(この場合はpython)にバインドされる方法に関する情報のソースとして、たとえばFFIのPythonctypes拡張モジュールのソースコードを使用できます。Pythonのソースコードとその標準モジュールは非常に読みやすいです。

これは、Davidが言及しているライブラリをPythonで使用する例です。

http://code.activestate.com/recipes/146847/

Python(C)のソースが利用可能であり、Python自体がDelphiの拡張機能である可能性があるため、最初にそれを使用できます。(RADツールの一部として)独自の完全な動的言語を作成する場合は、FFIの課題にも対応できます。

私は個人的に、完全で実行可能なプログラミング言語とそのすべてのライブラリをゼロから発明するという課題に取り組んでいないので、私が知っていることを一緒にハイブリッド化することを好みます。CまたはDelphiのネイティブコード、およびPythonの動的スクリプト。必要に応じて、3つすべてを1つのアプリケーションに簡単に組み合わせることができます。

于 2011-03-19T03:04:21.820 に答える