DLs

6791 ワード

DLs
原文の住所:http://www.vckbase.com/document/viewdoc/?id=1667 DLsを勉強していますが、高所高所高所高所高所から見下ろすという見解はありません.本文はコードを通してコードがどのように実行されているかを確認したいだけです.本論文では、カタログパスの設定など、コンパイラの特性を知っていると仮定します.
プロジェクトを作成するために、Win 32コンソールプロジェクト(Win 32 Consolie Aplication)を選択し、アプリケーション設定タグ(the advancend tab)上で、DLLと空の項目オプションを選択してください.DLsはあなたが思っているほど難しくないかもしれません.まずあなたの頭のファイルを書きます.DLT to rial.hという.このファイルは他のヘッダファイルと同じです.中には関数のプロトタイプだけです.
#ifndef _DLL_TUTORIAL_H_
#define _DLL_TUTORIAL_H_
#include <iostream> #if defined DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif

 

extern "C"
{
DECLDIR int Add( int a, int b );
DECLDIR void Function( void );
}
#endif
前の2行はコンパイラがこのファイルを一回だけ含むことを示しています.extern「C」はコンパイラにこの部分はC/C++で使用できると伝えています.
VC++には関数を導出する二つの方法があります.
     1、_うを使うdeclspec、Microsoft定義のキーワードです.
     2、モジュール定義ファイル(Module-Definition File.DEF)を作成します.第一の方法はやや第二の方法より簡単ですが、どちらもよく働きます.
同前declspecは関数記号をあなたのDLLの中の1つの記憶類に導出します.次の行が定義されるとDECLDIRを定義してこの関数を実行します.
#define DLL_EXPORT
同時に関数を導入します.もし次の行があれば.
#define DLL_EXPORT
ソースファイルには現れませんでした.この場合、関数Add(int a,int b)とFunction()を導出します.
今はDLT trol.cppと呼ばれるソースファイルを書く必要があります.
#include <iostream>
#include "DLL_Tutorial.h"

 

#define DLL_EXPORT extern "C"
{
DECLDIR int Add( int a, int b )
{
return( a + b );
} DECLDIR void Function( void )
{
std::cout << "DLL Called!" << std::endl;
} }
ここでは、すべての関数が定義されています.Int_Add(int a,int b)は、単純に2つの数を加算して、void Function(void)は、あなたのDLLが呼び出しられたときにのみ通知されます.DLLをどのように使うかを示す前に、モジュール定義ファイル(.def)の内容を教えたいです.
モジュール定義ファイル(.def)
モジュール定義ファイルは.defファイルの拡張子があるテキストファイルです.DLLの関数を導くために使われます._declspecと似ています.しかし.defファイルはMicrosoftで定義されていません.一つは.defファイルに必要な部分が二つしかありません.LIBREYとEXPORTSです.まず基本的なdefファイルを見てみます.後で解析します.
LIBRARY dll_tutorial
DESCRIPTION "our simple DLL"
EXPORTS
Add @1
Function @2
最初の行は'LIBRIRY''が必要な部分です.リンクはどのようにあなたのDLLを命名するかを教えてくれます.下に'DESCRIPTION'と表示されている部分は必要ではないですが、それを入れるのが好きです.この文は文字列を書き込みます.rdaa節[MSDNによると]このDLLを使って、このDLLは何をするかを訴えます.この部分は他のアプリケーションにアクセスして導入ライブラリを作成することができます.このプロジェクトを作成すると、一つだけではなく、一つのファイル拡張子が作成されます.libのエクスポートライブラリも作成されます.前の部分以外にも、他の4つのファイルがあります.この部分はNAME、STACKSIZE、SECTIONS、VERIONと表記されています.これらの内容はここでは取り上げられませんが、インターネットで検索すれば、いくつかのものが見つかると思います.
今はあなたのDLLを作成しました.どのようにアプリケーションでそれを使うかを学ぶ必要があります.このDLLが生成されたら、一つのファイルと一つの.libファイルを作成します.この二つは全部必要です.
隠しリンク
DLLをロードする方法は二つあります.もう一つの方法は近道です.もう一つの方法は複雑です.近道はあなたにリンクして、dllファイルを新しいプロジェクトのパスに入れます.そのため、新しい空のWin 32コンソールプロジェクトを作成して、ソースファイルを追加します.あなたが作ったDLLを新しいプロジェクトと同じディレクトリに入れます.
 
#include <iostream>
#include <DLLTutorial.h>

 

int main()
{
Function();
std::cout << Add(32, 58) << "
";
return(1);
}
DLT trol.libファイルにリンクする必要があります.プロジェクトのプロパティを設定しましたが、次のような文で代替できます.
#pragma comment(lib, "DLLTutorial.lib") 
私のDLLフォルダをコンパイラに確認させてください.libファイルは同時にこのディレクトリのDLLヘッダファイルを見させます.そうしたくないなら、いつも彼らをあなたの新しいプロジェクトのディレクトリに入れて、「」を使ってもいいです.これはDLLをロードする簡単な方法です.
リンクを表示
難点のロードDLLの方法はちょっと複雑です.関数ポインタとWindows関数が必要です.しかし、DLsをロードする方法によって、DLLの.libまたはヘッダファイルは不要です.DLLだけが必要です.以下にいくつかのコードを並べます.後で解析します.
#include <iostream>
#include <windows.h>

 

typedef int (*AddFunc)(int,int);
typedef void (*FunctionFunc)();

int main()
{
AddFunc _AddFunc;
FunctionFunc _FunctionFunc;
HINSTANCE hInstLibrary = LoadLibrary("DLL_Tutorial.dll"); if (hInstLibrary == NULL)
{
FreeLibrary(hInstLibrary);
}

_AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add");
_FunctionFunc = (FunctionFunc)GetProcAddress(hInstLibrary, "Function"); if ((_AddFunc == NULL) || (_FunctionFunc == NULL))
{
FreeLibrary(hInstLibrary);
} std::cout << _AddFunc(23, 43) << std::endl;
_FunctionFunc(); std::cin.get(); FreeLibrary(hInstLibrary); return(1);
}
まず注意します.ここにはファイル「windows.h」を入れて同時に「DLuTutorial.h」に移動しました.理由は簡単です.Windows関数がいくつか含まれていますので、もちろん今はその中のいくつかしか必要としません.また、いくつかのWindows特定変数が含まれています.DLUtorial.hを削除することができます.前に述べたように、この方法を使ってDLLをロードする時は必要ないからです.
次のように見えます.次のような形で古霊精変なコードがあります.
typedef int (*AddFunc)(int,int);
typedef void (*FunctionFunc)();
これは関数の指針です.DLLに関する自己学習ガイドですので、関数ポインタが本ガイドの範囲を超えています.したがって、今はDLLの関数の別名としてしか考えられません.末尾にFunncという名前が好きです.(int)部分はこの関数のパラメータ部分です.例えば、Add関数は2つの整数を得るために必要です.関数ポインタとしてのパラメータです.Function関数にはパラメータがありませんので、空にしてください.main()部分の前の2行は、DLL内部の関数と同じように宣言関数ポインタです.あらかじめ定義するのが好きです.
HINSTANCEは、Windowsデータのタイプです.例のハンドルです.この場合、このDLLは関数LoadLibrary()を使用してDLLのインスタンスを取得できます.名前をパラメータとして取得します.LoadLibrary関数を呼び出した後、関数の戻りが成功したかどうか確認してください.HINSTANCEがNULLに等しいかどうかを確認してください.(Windows.hで0またはWindows.hと定義されている先頭ファイル)が成功しているかどうかを確認します.NULLに等しい場合は、ハンドルが無効になり、このライブラリをリリースしなければなりません.つまり、DLLで得られたメモリを解放しなければなりません.もし関数が成功したら、あなたのHINSTANCEはDLLを指すハンドルを含みます.
DLLに向けたハンドルを取得すると、DLLから関数を再取得できます.このようにするためには、関数GetProcAddres()を使用して、DLLのハンドルと関数の名前をパラメータとして使う必要があります.関数ポインタをGetProcAddres(GetProcAddres)によって返さなければなりません.その関数で定義されている関数ポインタに変換します.例を挙げると、Add()関数に対しては、GetProcAddres()が必要です.AddFunncに変換します.これはパラメータと戻り値を知っている理由です.今はNULLに等しいかどうか、DLLの関数を持っているかどうかを先に決定したほうがいいです.これは簡単なif文です.もし一つがNULLに等しいなら、前に述べたようにライブラリを解放しなければなりません.
関数ポインタがDLLの関数を持っていると、今はそれらを使うことができますが、ここには関数の実際の名前は使えません.関数ポインタを使ってそれらを呼び出す必要があります.その後は、すべてのライブラリをリリースする必要があります.
今はDLLの基本的な知識を知っています.それらをどうやって作るか知っています.二つの違った方法でリンクする方法も知っています.ここにはまだもっと多くのことが必要です.しかし、私はそれらをあなたたち自身に教えて、より素晴らしい作者と探求して書きました.
例:空いているdllプロジェクトを構築する:新規作成する.hファイル菗ifdef DLl 1楽API萼else萼デfine DLl 1_API  _declspec(dlimport)萻endif
extern「C」DLl 1_APIint add(int a,int b)、extern「C」DLl 1_APIint subtract(int a,int b);
class DLL 1_APIPoint{public: void out Point(int x,int y);;;新規作成.cppファイル  _declspec(dlexport)葃include「Dll 1.h」
璣include萼include
int add(int a,int b){ return a+b;)
int subtract(int a,int b){ return a-b;)
void Point::outPoint(int x,int y){ HWND hwnd=GetForeground Window() HDC hdc=GetDC(hwnd) TCHAR buf[20]; memset(buf、0、20) ws printf(buf,L“x=%d,y=%d”,x,y); TextOut(hdc,0,buf,wcslen); ReleaseDC(hwnd,hdc);}コンパイルプロジェクトは、生成したdllと.libをアプリケーションの下に置く.