1.最初のDLLプロジェクトを開始します
1.file-> close all-> file-> new dll>
コード: |
//次のようにコードを自動的に生成します ライブラリProject2; //これはナンセンスです。 用途 sysutils、 クラス; {$ r *.res} 始める 終わり。 |
2。入力するfuncを追加します。
コード: |
ライブラリProject2; 用途 sysutils、 クラス; 関数mymax(x、y:整数):integer; 始める x> yの場合 結果:= x それ以外 結果:= y; 終わり ; //覚えておいてください:ライブラリの名前は重要ではありませんが、DLL-FUNCの場合は関連しています。 // dll-func-nameでmymaxを書くことはmymaxとは異なります。それが間違って書かれている場合、すぐに //その結果、このDLLを使用するAPをまったく開くことができないことを尋ねることができます。 //パラメーターの上限と小文字は問題ありません。同じ名前を持つ必要さえありません。プロトタイプが(x、y:整数)の場合 //時間内に(a、b:整数)としてそれを書きます、それは大丈夫です。 //覚えておいてください:別のstdcallを追加します。この本は、あなたがDelphiを使用してdllsを書いている場合、そしてだけでなく希望すると言っています // Delphi-APがBCB/VC-APなどを使用することを望んでいる場合は、stdcallを追加した方がいいです。 //パラメーターパターン:Delphiには多くの可変パターンがありますが、これはもちろんDLLのようなものではありません // Windows/DLLの母国語はCでなければなりません。したがって、DLLのパラメーターに出入りしたい場合は、 //ルールに従って可能な限り使用します。これら2つを書くと、後者は非常に問題になります。 cに慣れていない場合 //それが問題ない場合。後で説明します。 {$ r *.res} 始める 終わり。 |
3.これらの共有可能な機能をDLLから送信して、外の世界(それはあなたのdelphi-ap)の使用を許可します:Guangru
したがって、APはこれらを使用できません。エクスポートを追加する必要があります。
コード: |
{$ r *.res} 輸出 mymax; 始める 終わり。 |
4.わかりました、Ctrl-F9を押してコンパイルできます。現時点ではF9を押さないでください。 DLLは、F9を押すと、ERRORMSGを押すことはできません。この時点でDLLにエラーがある場合は、修正してください。 Ctrl-F9をもう一度押します。警告は現時点ではそこにあるかもしれませんが、それは問題ではありません。ただ勉強して見てみましょう。 Ctrl-F9をもう一度押してから、「完了、コンパイル」します。同じディレクトリに *.dllがあります。おめでとうございます、タスクは完了です。
2。テストを実施します:新しいアプリケーションを開きます:
1. Tbuttonを追加します
コード: |
showmessage(inttostr(mymax(30,50))); |
2。funcをキャッチするためにそこに行くようにexeに伝えます
コード: |
//フォームに追加、インターフェイス、var function mymax(x、integer):integer; // mytestdll.dll以前にDLLプロジェクト名を書き込みます // DLL名が上下になっているかどうかは関係ありません。ただし、拡張機能.dllを追加することを忘れないでください。 win95またはntで、 //拡張機能を追加する必要はありませんが、これらの2つのOSはますます少ない場合があります。拡張機能を追加する必要があります。 |
わかりました、それは簡単です。
上記の例は非常に簡単ですか? Delphiに精通している友人は、上記のコードが基本的に一般的なDelphiプログラムを作成することと同じであることを知ることができますが、TestDLL関数の後に追加のstdcallパラメーターがあり、testdll関数がエクスポートステートメントを使用して宣言されています。上記のコードをコンパイルするだけで、delphi.dllという動的リンクライブラリを入手できます。それでは、何が注意が必要なのか見てみましょう。 1. DLLで記述されたすべての機能または手順は、STDCallコールパラメーターを使用して追加する必要があります。 Delphi 1またはDelphi 2環境では、コールパラメーターは遠いです。 Delphi 3の後、このパラメーターはSTDCallに変更され、最適化されたレジスタパラメーターの代わりに標準のWin32パラメーター転送テクノロジーを使用する目的で変更されました。 STDCALLパラメーターを使用するのを忘れたのは、一般的なエラーです。その理由は、レジスタパラメーターがDelphiのデフォルトパラメーターであるためです。
2。記述された機能と手順は、エクスポートステートメントを使用して外部関数として宣言する必要があります。
ご覧のとおり、TestDLL関数は外部関数として宣言されます。これにより、関数を外部的に見ることができます。特定の方法は、「クイックビュー」関数を使用して、マウスを右クリックするだけでDLLファイルを表示することです。 (クイックビューオプションがない場合は、Windows CDからインストールできます。)TestDll関数は、エクスポートテーブルバーに表示されます。別の正当な理由は、このように宣言しない場合、私たちが書く機能は呼ばれないということです。これは誰も見たくないものです。
3.長い文字列型パラメーターと変数を使用する場合、ShareMemを参照する必要があります。
Delphiの文字列タイプは非常に強力です。通常の文字列の長さは最大256文字ですが、Delphiの文字列タイプはデフォルトで2Gに達することができます。 (はい、あなたはそれを正しく読みます、それは確かに2つのメガバイトです。)この時点で、文字列型パラメーター、変数、または記録情報の使用を主張する場合、Sharememユニットを参照する必要があります。 。使用ステートメントの後に最初に参照されたユニットです。次の例に示すように:
用途
Sharemem、
sysutils、
クラス;
もう1つのポイントは、ユニットファイル(*.PAS)の代わりにプロジェクトファイル(*.DPR)で同じことを行う必要があり、多くの誤解を引き起こすことです。これを行わないと、クラッシュを支払う可能性があります。文字列タイプの使用を避ける方法は、文字列タイプのパラメーター、変数などをpCherまたは略語として宣言することです(s:string [10]など)タイプです。同じ問題は、動的配列を使用するときに発生します。ソリューションは上記のとおりです。
第3章:DelphiのDLLトップへの静的コール
DLLを呼び出すのは、DLLを書くよりも簡単です。まず、静的呼び出し方法を紹介します。後で動的通話方法を紹介し、2つの方法を比較します。同様に、まず静的コールの例を挙げましょう。
ユニットユニット1;
インタフェース
用途
Windows、メッセージ、sysutils、クラス、グラフィックス、
コントロール、フォーム、ダイアログ、stdctrls;
タイプ
tform1 = class(tform)
編集1:tedit;
Button1:Tbutton;
手順button1click(sender:tobject);
プライベート
{プライベート宣言}
公共
{公開宣言}
終わり;
var
form1:tform1;
実装
{$ r *.dfm}
//この行の次のコードは、私たちが本当に書いたコードです
関数testdll(i:integer):integer; stdcall;
外部「delphi.dll」;
手順tform1.button1click(sender:tobject);
始める
edit1.text:= inttostr(testdll(1));
終わり;
終わり。
上記の例では、フォームに編集ボックス(編集)とボタンを配置し、書いたばかりのdelphi.dllをテストするためのコードをほとんど書きました。私たちが行う唯一の仕事は、実装にTestDLL関数の説明の一部を配置し、外部ステートメントを使用してDelphi.dllの場所を指定することであることがわかります。 (この例では、コールプログラムとdelphi.dllは同じディレクトリにあります。)私たちが書いたtestdll関数がDelphiによってすぐに認識されたことはエキサイティングです。このような実験を行うことができます。「testdll(」を入力してください。すぐにデルフィは、fly-byプロンプトバーを使用して、入力すべきパラメーターを促します。
次:
1. stdcallを使用してパラメーターを呼び出します。
上記のように、DLLの関数と手順を参照する場合、上記と同じ理由で、STDCallパラメーターも使用する必要があります。
2。外部ステートメントを使用して、呼び出されたDLLファイルのパスと名前を指定します。
ご覧のとおり、外部ステートメントで呼び出されるDLLファイルの名前を指定します。 DLLファイルとそれを呼ぶメインプログラムが同じディレクトリにあるため、書き込みパスはありません。 DLLファイルがC:/にある場合、上記の参照ステートメントを外部「C:/delphi.dll」として記述できます。ファイルのsuffix.dllを記述する必要があることに注意してください。
3.グローバル変数はDLLから呼び出すことはできません。
次のようなDLLで何らかのグローバル変数を宣言した場合:var s:byte。このようにして、グローバル変数は通常DLLで使用できますが、Sは呼び出しプログラムでは使用できず、Sは呼び出しプログラムのグローバル変数として渡すことはできません。ただし、呼び出しプログラムで宣言された変数は、DLLのパラメーターとして渡すことができます。
4。呼び出されたDLLが存在する必要があります。
これは重要です。静的コールメソッドを使用する場合、DLLファイルが呼び出されることが必要です。指定されたパスとファイル名が存在しない場合、または指定されたパスとファイル名が正しくない場合、システムはメインプログラムを実行するときに「プログラムの開始中にエラーが発生しました」または「見つかりません *.dllファイル」をプロンプトします。
第4章は、DelphiのDLLトップを動的に呼び出します
動的にDLLを呼び出すことは比較的複雑ですが、非常に柔軟です。問題を徹底的に説明するために、今回はC ++で記述されたDLLを呼び出す例を示します。まず、C ++で次のDLLソースプログラムをコンパイルします。
#含む
extern "c" _declspec(dllexport)
int winapi testc(int i)
{
私を返します。
}
コンパイル後、DLLファイルが生成されます。便利なため、上記の呼び出しプログラムを参照していますが、Button1Clickプロセスの元のステートメントを次のコードに置き換えます。
手順tform1.button1click(sender:tobject);
タイプ
tintfunc = function(i:integer):integer; stdcall;
var
TH:サンドル;
TF:Tintfunc;
TP:tfarproc;
始める
TH:= LoadLibrary( 'cpp.dll');
th> 0の場合
試す
TP:= getProcAddress(TH、PCHAR( 'testc'));
tp <> nilの場合
次に、始めます
TF:= tintfunc(tp);
edit1.text:= inttostr(tf(1));
終わり
それ以外
showmessage( 'testc function not fund');
ついに
Freelibrary(TH);
終わり
それ以外
showmessage( 'cpp.dll not found');
終わり;
あなたが見たように、この動的な呼び出し手法は非常に複雑ですが、LoadLibraryのDLL名を変更するなどのパラメーターを変更する限り、「delphi.dll」になる限り、あなたは動的に変更できます。 dllと呼ばれます。
1.呼び出される関数または手順のタイプを定義します。
上記のコードでは、呼び出される関数TestCに対応するTintFuncタイプを定義します。他の呼び出しで同じ定義作業を行う必要があります。また、stdcallコールパラメーターを追加します。
2。呼び出されたDLLをリリースします。
LoadLibraryを使用してDLLを動的に呼びましたが、使用後にFreelibraryでDLLを手動でリリースする必要があることを忘れないでください。そうしないと、DLLはWindowsを出るかシャットダウンするまでメモリを取ります。
次に、DLLを呼び出す2つの方法の利点と欠点を評価しましょう。静的方法は、実装が簡単で、マスターが簡単で、一般的にはより安全で信頼性が高くなります。 DLLがプログラムの終わりにのみリリースされるまで実行され、Delphiなどのコンパイラベースのシステムのみがこの方法を使用できます。動的な方法は、静的な方法の欠点をよりよく解決し、DLLの関数と手順に簡単にアクセスできます関数または手順は、多くの複雑なタイプと呼び出し方法を定義する必要があります。初心者の場合、著者は静的方法を使用し、熟練した後に動的通話方法を使用することを推奨します。
第5章DLLトップを使用するための実用的なヒント
1。ライティングスキル。
1. DLLの正確性を確保するために、まず通常のアプリケーションの一部として記述し、正しくデバッグしてから、メインプログラムから分離してDLLにコンパイルできます。
2。DLLの普遍性を確保するには、次のようなdllに視覚的なコントロールの名前が表示されないようにする必要がありますいくつかの記録。
3。デバッグを容易にするために、各機能とプロセスは可能な限り短く簡潔であり、具体的かつ詳細な注釈を伴う必要があります。
4.財政的に、可能なエラーと例外を扱うために使用する必要があります。
5. DLLのサイズを減らすために、できるだけ少ないユニットを参照してください。特に、ダイアログユニットなどの視覚ユニットを参照しないでください。たとえば、一般に、クラスユニットを参照することはできません。これにより、コンパイルされたDLLを約16kb減らすことができます。
2。スキルを呼び出します。
1.静的メソッドを使用する場合、呼び出された関数または手順の名前を変更できます。上記のC ++で記述されたDLL例では、extern "c"ステートメントが削除された場合、C ++はいくつかの奇妙な関数名をコンパイルし、元のtestc関数は @testc $ sおよび他のばかげた奇妙な名前ですC ++名のマングリングテクノロジーを使用します。この関数名はDelphiでは違法です。この問題を解決できます。
参照関数を次のように書き直します
関数testc(i:integer):integer; stdcall;
外部 'cpp.dll'; name '@testc $ s';
名前の関数は名前を変更することです。
2。WindowsディレクトリまたはWindows/Systemディレクトリに書いたDLLを配置できます。そうすることで、外部ステートメントやLoadLibraryステートメントにパスを書くことなく、DLLの名前のみを書くことができます。しかし、これを行うのは少し不適切ですあなたが書いたDLLをシステムディレクトリに入れてください!
3。デバッグスキル。
1. DLLを実行できないことを知っています。これを行う方法があります。つまり、実行|パラメーターメニューでホストプログラムを設定します。ホストプログラムの名前をローカルページのホストアプリケーションバーに追加して、ステップバイステップのデバッグ、ブレークポイントの観察、および実行を実行します。
2。DLLバージョン情報を追加します。冒頭の備考は、バージョン情報がDLLにとって非常に重要であると述べました。このような小さなスペースを追加する価値があります。残念ながら、プロジェクト|オプションメニューを直接使用することはできません。次の例に示すように:
図書館デルフィ;
用途
sysutils、
クラス;
{$ r *.res}
//上記のコード行をこの位置に追加する必要があることに注意してください
関数testdll(i:integer):integer; stdcall;
始める
結果:= i;
終わり;
輸出
testdll;
始める
終わり。
3.他のDLLとの名前の複製を避けるために、書いたDLLに名前を付けるときに、文字、数字、アンダースコアの組み合わせを使用することをお勧めします。たとえば、jl_try16.dll。
4. Delphi 1またはDelphi 2ですでにいくつかのDLLをコンパイルしている場合、コンパイルしたDLLは16ビットです。 New Delphi 3またはDelphi 4環境のソースコードを再コンパイルするだけで、32ビットDLLを取得できます。
[後のメモ]:上記で紹介したDLLを使用する最も一般的に使用される方法に加えて、DLLはリソースキャリアとしても使用できます。たとえば、Windowsのアイコンの変更は、使用されるDLLのリソースです。さらに、DLL設計テクノロジーを習得したことで、より高度なOLE、COM、ActiveXプログラミングを使用するための多くの利点があります。