久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Delphi DLL制作和加载 Static, Dynamic, Delayed 以及 Shared-Memory Manager

發布時間:2024/4/14 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Delphi DLL制作和加载 Static, Dynamic, Delayed 以及 Shared-Memory Manager 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一 Dll的制作一般分為以下幾步:
1 在一個DLL工程里寫一個過程或函數
2 寫一個Exports關鍵字,在其下寫過程的名稱。不用寫參數和調用后綴。
二 參數傳遞
1 參數類型最好與window C++的參數類型一致。不要用DELPHI的數據類型。
2 最好有返回值[即使是一個過程],來報出調用成功或失敗,或狀態。成功或失敗的返回值最好為1[成功]或0[失敗].一句話,與windows c++兼容。
3 用stdcall聲明后綴。
4 最好大小寫敏感。
5 無須用far調用后綴,那只是為了與windows 16位程序兼容。

三 DLL的初始化和退出清理[如果需要初始化和退出清理]
1 DLLProc[SysUtils單元的一個Pointer]是DLL的入口。在此你可用你的函數替換了它的入口。但你的函數必須符合以下要求[其實就是一個回調函數]。如下:
procedure DllEnterPoint(dwReason: DWORD);far;stdcall;
dwReason參數有四種類型:
DLL_PROCESS_ATTACH:進程進入時
DLL_PROCESS_DETACH進程退出時
DLL_THREAD_ATTACH 線程進入時
DLL_THREAD_DETACH 線程退出時
在初始化部分寫:
DLLProc := @DLLEnterPoint;
DllEnterPoint(DLL_PROCESS_ATTACH);
2 如Form上有TdcomConnection組件,就Uses Activex,在初始化時寫一句CoInitialize (nil);
3 在退出時一定保證DcomConnection.Connected := False,并且數據集已關閉。否則報地址錯。

四 全局變量的使用
在widnows 32位程序中,兩個應用程序的地址空間是相互沒有聯系的。雖然DLL在內存中是一份,但變量是在各進程的地址空間中,因此你不能借助dll的全局變量來達到兩個應用程序間的數據傳遞,除非你用內存映像文件。

五 調用靜態載入
1 客戶端函數聲名:
1)大小寫敏感。
2)與DLL中的聲明一樣。
如: showform(form:Tform);Far;external'yproject_dll.dll';
3)調用時傳過去的參數類型最好也與windows c++一樣。
4)調用時DLL必須在windows搜索路徑中,順序是:當前目錄;Path路徑;windows;widows\system;windows\ssystem32;

六 調用動態載入
1 建立一種過程類型[如果你對過程類型的變量只是一個指針的本質清楚的話,你就知道是怎么回事了]。如:
type
mypointer=procedure(form:Tform);Far;external;
var
Hinst:Thandle;
showform:mypointer;
begin
Hinst:=loadlibrary('yproject_dll');//Load一個Dll,按文件名找。
showform:=getprocaddress(Hinst,'showform');//按函數名找,大小寫敏感。如果你知道自動化對象的本質就清楚了。
showform(application.mainform);//找到函數入口指針就調用。
Freelibrary(Hinst);
end;

七 在DLL建立一個TForM
1 把你的Form Uses到Dll中,你的Form用到的關聯的單元也要Uses進來[這是最麻煩的一點,因為你的Form或許Uses了許多特殊的單元或函數]
2 傳遞一個Application參數,用它建立Form.

八 在DLL中建立一個TMDIChildForM
1 Dll中的MDIForm.FormStyle不用為fmMDIChild.
2 在CreateForm后寫以下兩句:


function ShowForm(mainForm:TForm):integer;stdcall
var
Form1: TForm1;
ptr:PLongInt;
begin
ptr:=@(Application.MainForm);//先把dll的MainForm句柄保存起來,也無須釋放,只不過是替換一下

ptr^:=LongInt(mainForm);//用主調程序的mainForm替換DLL的MainForm。MainForm是特殊的WINDOW,它專門管理Application中的Forms資源.

//為什么不直接Application.MainForm := mainForm,因為Application.MainForm是只讀屬性

Form1:=TForm1.Create(mainForm);//用參數建立
end;


備注:參數是主調程序的Application.MainForm

九 示例:
DLL源代碼:

library Project2;uses SysUtils, Classes, Dialogs, Forms, Unit2 in 'Unit2.pas' {Form2};{$R *.RES} var ccc: Pchar;procedure OpenForm(mainForm:TForm);stdcall; var Form1: TForm1; ptr:PLongInt; begin ptr:=@(Application.MainForm); ptr^:=LongInt(mainForm); Form1:=TForm1.Create(mainForm); end;procedure InputCCC(Text: Pchar);stdcall; begin ccc := Text; end;procedure ShowCCC;stdcall; begin ShowMessage(String(ccc)); end;exports OpenForm; InputCCC, ShowCCC; begin end.

?調用方源代碼:

unit Unit1;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.DFM} procedure OpenForm(mainForm:TForm);stdcall;External'project2.dll'; procedure ShowCCC;stdcall;External'project2.dll'; procedure InputCCC(Text: Pchar);stdcall;External'project2.dll';procedure TForm1.Button1Click(Sender: TObject); var Text: Pchar; begin Text := Pchar(Edit1.Text); // OpenForm(Application.MainForm);//為了調MDICHILD InputCCC(Text);//為了實驗DLL中的全局變量是否在各個應用程序間共享 end;procedure TForm1.Button2Click(Sender: TObject); begin ShowCCC;//這里表明WINDOWS 32位應用程序DLL中的全局變量也是在應用程序地址空間中,16位應用程序或許不同,沒有做實驗。 end;

How to create DLL s using Delphi

Introduction

DLL means Dynamic Link Libraries.

As the name implies , dll is a collection of functions and procedures in a place which can be used in other applications.

Basic idea of creating DLLs is to share functions and procedures across languages.

DLL files will have an extension of .dll.

How to create a dll using Delphi?

It's not so hard to create a dll as you heard.

Using Delphi it's very easy.

Select the menu File -> New -> Other... from Delphi IDE.

This will open a dialog box.

From there select the "DLL Wizard" icon .

A new project will be opened with a new unit.

This unit file will be little bit different from the normal unit files.

In the normal units , the first line will contain a keyword unit and the respective unitname.

But the unit created in dll , the first keyword will be library instead of unit as given below.

library DLLProject;uses SysUtils, Classes;{$R *.RES}begin end.

Now you can add as many functions and procedures under the uses clause.

The functions and procedures that are required to be called from other applications

should be exported using the clause?Exports.

The name used along with the library clause will become the name of the dll. In this case our dll will be?DLLProject.dll

Suppose you have 3 functions as shown below.

Function SubFunc():Integer; begin ... end;Procedure SubProc(); begin ... end;Function MainFunc():Integer; begin ... SubFunc; SubProc; ... end;Exports MainFunc;begin end;

Here we have 2 functions and one procedure .

The?MainFunc?is the main function which calls other 2 functions and here we are exporting MainFunc only.

That means?MainFunc?is the only function which can be called from outside.

If you need to export any other function or procedure , you have to include it under the?Exports?clause.

Dll loading

Now we can see how these dll [exported] functions can be called from other applications.

The dll function/procedure has to be declared in the global section [before implementation section]

of the unit file where the it has to be called. The syntax should be

var procedure MainFunc ():Integer; external 'DLLProject.dll';Implementation.end;

This kind of loading a dll is called static loading.

Because compiler try to load the dll when it loads the application itself.

So if the dll is missing in the search path , you'll get an erroro message while starting your application itself.

Now we'll see another kind of dll loading named Dynamic loading.

This kind of loading require extra commands to load dll , call your dll function and release the dll from memory.

The dll will be loaded in the memory whenever you call the LoadLibrary function.

It won't be loaded when your application starts.

So if the dll is missing in your search path, you won't get any error message during the start up of your application.

The dll should be loaded using the command?LoadLibrary?which returns the handle to the dll once it's loaded to the memory.

If there is any problem in loading, the handle will return 0.

Once dll is loaded properly in to the memory, we have to gather the address of the function\procedure to be called.

This can be done using the function?GetProcAddress?which returns the address of the dll function.

To receive the return value , you have to have a variable of type function or procedure [TDllAddr = function : Integer;?].

Have a look at the example shown below.

typeTDllAddr = function : Integer;var DllAddr : TDllAddr;beginDllHandle := LoadLibrary("DLLProject.dll"); if DllHandle <> 0 then begin @DllAddr := GetProcAddress(DllHandle , 'MainProc'); DllAddr(); // Calling dll function end;end;

Finally, the memory allocated for the dll has to be explicitly released using the?FreeLibrary?function.

Note?:

The dll function parameters should be windows types.

If you have any String type parameter in dll function/procedure ,

then you have include ShareMem unit in the dll.

Not only that, Sharemem unit should be the first unit in the uses clause.

?

Writing Dynamically Loaded Libraries

Note:?Libraries are significantly more limited than packages in what they can export.

Libraries cannot export constants, types, and normal variables.

That is, class types defined in a library will not be seen in a program using that library.

To export items other than simple procedures and functions,?

packages?are the recommended alternative.

Libraries should only be considered when interoperability with other programming is a requirement.

The following topics describe elements of writing dynamically loadable libraries, including

  • The exports clause.
  • Library initialization code.
  • Global variables.
  • Libraries and system variables.

Using Export Clause in Libraries

The main source for a dynamically loadable library is identical to that of a program, except that it begins with the reserved word?library?(instead of?program).

Only routines that a library explicitly exports are available for importing by other libraries or programs. The following example shows a library with two exported functions,?Min?and?Max:

library MinMax; function Min(X, Y: Integer): Integer; stdcall; beginif X < Y then Min := X else Min := Y; end; function Max(X, Y: Integer): Integer; stdcall; beginif X > Y then Max := X else Max := Y; end; exportsMin,Max;beginend.

?

If you want your library to be available to applications written in other languages,

it's safest to specify?stdcall?in the declarations of exported functions.

Other languages may not support Delphi's default?register?calling convention.

Libraries can be built from multiple units.

In this case, the library source file is frequently reduced to a?uses?clause, an?exports?clause, and the initialization code.

For example:

library Editors;
uses
EdInit, EdInOut, EdFormat, EdPrint;
exportsInitEditors,DoneEditors name Done,InsertText name Insert,DeleteSelection name Delete,FormatSelection,PrintSelection name Print,...SetErrorHandler;
beginInitLibrary;end.

?

?

?

You can put?exports?clauses in the?interface?or?implementation?section of a unit.

Any library that includes such a unit in its?uses?clause

automatically exports the routines listed the unit's?exports?clauses

without the need for an?exports?clause of its own.

?


A routine is exported when it is listed in an?exports?clause, which has the form:

exports entry1, ..., entryn;

where each entry consists of the name of a procedure, function,

or variable (which must be declared prior to the?exports?clause),

followed by a parameter list (only if exporting a routine that is overloaded),

and an optional?name?specifier.

You can qualify the procedure or function name with the name of a unit.

(Entries can also include the directive?resident, which is maintained for backward compatibility and is ignored by the compiler.)

On the Win32 platform, an?index?specifier consists of the directive?index?followed by a numeric constant between 1 and 2,147,483,647.

(For more efficient programs, use low index values.)

If an entry has no?index?specifier, the routine is automatically assigned a number in the export table.

Note:?Use of?index?specifiers, which are supported for backward compatibility only,
is discouraged and may cause problems for other development tools.

A?name?specifier consists of the directive?name?followed by a string constant.

If an entry has no?name?specifier, the routine is exported under its original declared name,
with the same spelling and case. Use a?name?clause when you want to export a routine under a different name.
For example:

exports DoSomethingABC name 'DoSomething';

When you export an overloaded function or procedure from a dynamically loadable library,
you must specify its parameter list in the?exports?clause.

For example:

exports Divide(X, Y: Integer) name 'Divide_Ints', Divide(X, Y: Real) name 'Divide_Reals';

?

On Win32, do not include?index?specifiers in entries for overloaded routines.

An?exports?clause can appear anywhere and any number of times in the declaration part of a program or library,

or in the?interface?or?implementation?section of a unit.

Programs seldom contain an?exports?clause.

Library Initialization Code

The statements in a library's block constitute the library's initialization code.

These statements are executed once every time the library is loaded.

They typically perform tasks like registering window classes and initializing variables.

Library initialization code can also install an entry point procedure using the?DllProc?variable.

The?DllProc?variable is similar to an exit procedure, which is described in Exit procedures;

the entry point procedure executes when the library is loaded or unloaded.

Library initialization code can signal an error by setting the?ExitCode?variable to a nonzero value.

ExitCode is declared in the?System unit and defaults to zero, indicating successful initialization.

If a library's initialization code sets?ExitCode?to another value,

the library is unloaded and the calling application is notified of the failure.

Similarly, if an unhandled exception occurs during execution of the initialization code,

the calling application is notified of a failure to load the library.

Here is an example of a library with initialization code and an entry point procedure:

library Test; varSaveDllProc: Pointer;
procedure LibExit(Reason: Integer); beginif Reason = DLL_PROCESS_DETACH thenbegin.. // library exit code.end;SaveDllProc(Reason); // call saved entry point procedure end;
begin.. // library initialization code.SaveDllProc := DllProc; // save exit procedure chainDllProc := @LibExit; // install LibExit exit procedure end.

?

?

?

DllProc?is called when the library is first loaded into memory,

when a thread starts or stops,

or when the library is unloaded.

The initialization parts of all units used by a library are executed before the library's initialization code,

and the finalization parts of those units are executed after the library's entry point procedure.

?

Global Variables in a Library

?

Global variables declared in a shared library cannot be imported by a Delphi application.

?

A library can be used by several applications at once,

but each application has a copy of the library in its own process space with its own set of global variables.

For multiple libraries - or multiple instances of a library - to share memory,

they must use memory-mapped files.

Refer to the your system documentation for further information.

?

Libraries and System Variables

?

Several variables declared in the?System?unit are of special interest to those programming libraries.

Use IsLibrary to determine whether code is executing in an application or in a library;

IsLibrary is always?False?in an application and?True?in a library.

During a library's lifetime,?HInstance?contains its instance handle.?

CmdLine?is always?nil?in a library.

?

The DLLProc variable allows a library to monitor calls that the operating system makes to the library entry point.

This feature is normally used only by libraries that support multithreading.

DLLProc is used in multithreading applications.

You should use finalization sections, rather than exit procedures, for all exit behavior.

?

To monitor operating-system calls, create a callback procedure that takes a single integer parameter, for example:

procedure DLLHandler(Reason: Integer);

?

and assign the address of the procedure to the?DLLProc?variable.

When the procedure is called, it passes to it one of the following values.

DLL_PROCESS_DETACH

Indicates that the library is detaching from the address space of the calling process as a result of a clean exit or a call to?FreeLibrary.

DLL_PROCESS_ATTACH

Indicates that the library is attaching to the address space of the calling process as the result of a call to?LoadLibrary.

DLL_THREAD_ATTACH

Indicates that the current process is creating a new thread.

DLL_THREAD_DETACH

Indicates that a thread is exiting cleanly.


In the body of the procedure, you can specify actions to take depending on which parameter is passed to the procedure.

Exceptions and Runtime Errors in Libraries

When an exception is raised but not handled in a dynamically loadable library,

it propagates out of the library to the caller.

If the calling application or library is itself written in Delphi,

the exception can be handled through a normal?try...except?statement.

On Win32, if the calling application or library is written in another language,

the exception can be handled as an operating-system exception with the exception code?$0EEDFADE.

The first entry in the?ExceptionInformation?array of the operating-system exception record

contains the exception address, and the second entry contains a reference to the Delphi exception object.

Generally, you should not let exceptions escape from your library.

Delphi exceptions map to the OS exception model.

If a library does not use the?SysUtils?unit, exception support is disabled.

In this case, when a runtime error occurs in the library, the calling application terminates.

Because the library has no way of knowing whether it was called from a Delphi program,

it cannot invoke the application's exit procedures;

the application is simply aborted and removed from memory.

Shared-Memory Manager

On Win32, if a DLL exports routines that pass long strings or dynamic arrays as parameters or function results

(whether directly or nested in records or objects), then the DLL and its client applications (or DLLs) must all use the?ShareMem?unit.

The same is true if one application or DLL allocates memory with?New?or?GetMem?which

is deallocated by a call to?Dispose?or?FreeMem?in another module.?

ShareMem?should always be the first unit listed in any program or library?uses?clause where it occurs.

ShareMem?is the interface unit for the?BORLANDMM.DLL?memory manager,

which allows modules to share dynamically allocated memory.?

BORLANDMM.DLL?must be deployed with applications and DLLs that use?ShareMem.

When an application or DLL uses?ShareMem,

its memory manager is replaced by the memory manager in?BORLANDMM.DLL.

?

Static vs. Dynamic Dynamic Link Library Loading - A Comparison

A?DLL?or a dynamic link library acts as a shared library of function, that can be called by applications and by other DLLs.

Using Delphi, you can create and use our own DLLs, you can call functions in DLLs developed with other programming languages / by other developers.

If you are new to working with DLLs, make sure you read?Introduction to DLLs.

Static or Dynamic Loading?

When you want to call a function exported by a DLL, one question comes up:?should you use static or dynamic DLL loading??.

Before you can call routines defined in DLL, you must import them. Functions exported from a DLL can be imported in two ways:

by declaring an external procedure or function (static),

or by direct calls to DLL specific API functions (dynamic).

Let's create a simple DLL. Here's the code to the "circle.dll"

exporting one function "CircleArea" which calculates the area of a circle using the given radius:

library circle;

uses SysUtils, Classes, Math;

{$R *.res}

function CircleArea(const radius : double) : double; stdcall;
begin
result := radius * radius * PI;
end;

exports CircleArea;

begin
end.

?

Note: if you need help with creating a DLL using Delphi, read the?How to create (and use) a DLL in Delphi?.

Once you have the circle.dll you can use the exported "CircleArea" function from your application.

Static Loading

The simplest way to import a procedure or function is to declare it using the external directive:

function CircleArea(const radius : double) : double; external 'circle.dll';

?

?If you include this declaration in the?interface part?of a unit,

circle.dll is loaded once, when the program starts.

Throughout execution of the program, the function CircleArea is available

to all units that use the unit where the above declaration is.

Dynamic Loading

You can access routines in a library through direct calls to Win32 APIs,

including LoadLibrary?,?FreeLibrary?, andGetProcAddress?.

These functions are declared in Windows.pas.

Here's how to call the CircleArea function using dynamic loading:

type TCircleAreaFunc = function (const radius: double) : double; stdcall; var dllHandle : cardinal; circleAreaFunc : TCircleAreaFunc; begin dllHandle := LoadLibrary('circle.dll') ; if dllHandle <> 0 then begin @circleAreaFunc := GetProcAddress(dllHandle, 'CircleArea') ; if Assigned (circleAreaFunc) then circleAreaFunc(15) //call the function else ShowMessage('"CircleArea" function not found') ; FreeLibrary(dllHandle) ; end else begin ShowMessage('circle.dll not found / not loaded') ; end; end;

??

When you import using dynamic loading, the DLL is not loaded until the call to LoadLibrary.

The library is unloaded by the call to FreeLibrary.

With static loading the DLL will be loaded and its initialization sections will execute

before the calling application's initialization sections are executed.

With dynamic loading, this is reversed.

Static or Dynamic

Let's now compare static and dynamic DLL loading to see what are advantages and disadvantages of both.

Static loading PROS:

  • More easy for a beginner developer, no "ugly" API calls.
  • DLLs loaded once, when the program starts.

Static loading CONS:

  • The application will NOT start if any DLLs are missing (cannot be found).
    When you run the program you will see an ugly message:?
    "This application has failed to start because 'missing.dll' was not found. Re-installingn the application may fix this problem".?
    By design the DLL search order with static linking includes:
    the directory from which the application loaded,
    the system directory,
    the Windows directory,
    directories listed in the PATH environment variable.?

    Note also that the search order might be different for various Windows versions.?
    The safest is to always expect to have all the DLLs in the directory where the calling application is.

  • More memory used, as all DLLs are loaded even if you will not use some of the functions.

Dynamic loading PROS:

  • You can run your program even when some of the libraries it uses are not present.
  • Smaller memory consumption - DLLs used when needed.
  • You can specify the full path to the DLL.
  • Use for functionality that is rarely needed by the application.
  • Could be used for modular applications. The application only exposes (loads) modules (dlls) "approved" for the user.
  • The ability to load and unload library dynamically,
    is the foundation of a plug-in system that allow a developer to add extra functionality to programs.
  • Backwards compatibility with older Windows versions,
    in which system dlls may not support the same functions or in the same way.
    Detecting the Windows version first, then dynamic linking based on what your app is running on,
    allows you to support more versions of Windows and provide work arounds for older OSs,
    or at the very least gracefully disabling features you can't support.

Dynamic loading CONS:

  • Requires more code, not trivial for a beginner developer.

I hope differences are clear and that you will know what type of DLL loading to use for your next project ;)

If you think some PROS or CONS are missing, feel free to let me know - I'll add it to the list.

?

Libraries and Packages (Delphi)?

A dynamically loadable library is a dynamic-link library (DLL) on Windows, or a?DYLIB?on Mac.

It is a collection of routines that can be called by applications and by other DLLs or shared objects.

Like units, dynamically loadable libraries contain sharable code or resources.

But this type of library is a separately compiled executable that is linked, at run time, to the programs that use it.

Delphi programs can call DLLs and assemblies written in other languages,

and applications written in other languages can call DLLs or assemblies written in Delphi.

Calling Dynamically Loadable Libraries

You can call operating system routines directly, but they are not linked to your application until run time.

This means that the library need not be present when you compile your program.

Also, there is no compile-time validation of attempts to import a routine.

Before you can call routines defined in DLL or assembly, you must import them.

This can be done in two ways:

by declaring an?external?procedure or function, or by direct calls to the operating system.

Whichever method you use, the routines are not linked to your application until run time.

Delphi does not support importing variables from DLLs or assemblies.

Static Loading

The simplest way to import a procedure or function is to declare it using the?external?directive.

For example:

procedure DoSomething; external 'MYLIB.DLL';

?

?If you include this declaration in a program,?MYLIB.DLL?is loaded once, when the program starts.

Throughout the execution of the program, the identifier?DoSomething?always refers to the same entry point in the same shared library.

Declarations of imported routines can be placed directly in the program or unit where they are called.

To simplify maintenance, however, you can collect?external?declarations into a separate "import unit"

that also contains any constants and types required for interfacing with the library.

Other modules that use the import unit can call any routines declared in it.

Dynamic Loading (Windows-only)

You can access routines in a library through direct calls to Windows APIs,

including?LoadLibrary,?FreeLibrary, and?GetProcAddress.

These functions are declared in?Windows.pas.

In this case, use procedural-type variables to reference the imported routines.

For example:

uses Windows, ...;typeTTimeRec = recordSecond: Integer;Minute: Integer;Hour: Integer;end;TGetTime = procedure(var Time: TTimeRec);THandle = Integer; var Time: TTimeRec; Handle: THandle; GetTime: TGetTime; . . . begin Handle := LoadLibrary('libraryname'); if Handle <> 0 then begin @GetTime := GetProcAddress(Handle, 'GetTime'); if @GetTime <> nil then begin GetTime(Time); with Time do Writeln('The time is ', Hour, ':', Minute, ':', Second); end; FreeLibrary(Handle); end; end;

When you import routines this way, the library is not loaded

until the code containing the call to?LoadLibrary?executes.

The library is later unloaded by the call to?FreeLibrary.

This allows you to conserve memory and to run your program

even when some of the libraries it uses are not present.??

Delayed Loading

The?delayed?directive can be used to decorate an?external?routine to delay the loading of the library containing the routine.

The actual loading happens when the routine is called for the first time.

The following example demonstrates the use of the?delayed?directive:

function GetSomething: Integer; external 'somelibrary.dll' delayed;

?

In the example above, the?GetSomething?routine is imported from the?somelibrary.dll?library.

The delayed directive ensures thatsomelibrary.dll?is not statically linked to the application, but rather dynamically.

The?delayed?directive is useful in the case where the imported routines do not exist on the target operating system on which the application is run.

Statically imported routines require that the operating system find and load the library when the application is started.

If the routine is not found in the loaded library, or the library does not exist, the Operating System halts the execution of the application.

Using the?delayed?directive enables you to check, at run time, whether the Operating System supports the required APIs;

only then you can call the imported routines.

Another potential use for the?delayed?directive is related to the memory footprint of the application:

decorating the less probably to be used routines, as?delayed?may decrease the memory footprint of the application,

because the libraries are loaded only when required.

The abusive use of?delayed?can damage the speed performance of the program (as perceived by the end user).

Note:?

Trying to call a delayed routine that cannot be resolved results in a run-time error (or an exception, if the SysUtils unit is loaded).

In order to fine-tune the delay-loading process used by the Delphi Run-time Library,

you can register hook procedures to oversee and change its behavior.

To accomplish this, use?SetDliNotifyHook2?and?SetDliFailureHook2, declared in the SysInit unit.

Also see the code example at?Delayed Loading (Delphi).

This example demonstrates the fine tuning of the delay loading mechanism.

Using the provided functionality, you can hook-up various steps in the delay loading process.

This example defines three cases, one of which is correct, and two incorrect.?

Note:?

At the XE2 release, the delayed loading mechanism for Delphi was

refactored and moved From the System unit into the?SysInit?unit.

For example, System.dliNotification became?SysInit.dliNotification,

and System.DliNotifyHook became?SysInit.DliNotifyHook2.

This code example has not yet been revised to use the new delayed loading.

program TestDelayLoad;{$APPTYPE CONSOLE}usesWinapi.Windows,System.SysUtils;function GetDesktopWindow: HWND; stdcall; external user32 name 'GetDesktopWindow' delayed; function GetFooBar: Integer; stdcall; external kernel32 name 'GetFooBar' delayed; function GetFooBarBar: Integer; stdcall; external 'kernel33' name 'GetFooBarBar' delayed;varLOldNotifyHook, LOldFailureHook: TDelayedLoadHook; { for storing the old hook pointers }{ Utility function to retrieve the name of the imported routine or its ordinal } function ImportName(const AProc: TDelayLoadProc): String; inline; beginif AProc.fImportByName thenResult := AProc.szProcNameelseResult := '#' + IntToStr(AProc.dwOrdinal); end;function MyDelayedLoadHook(dliNotify: dliNotification; pdli: PDelayLoadInfo): Pointer; stdcall; begin{ Write a message for each dli notification }case dliNotify ofdliNoteStartProcessing:WriteLn('Started the delayed load session for "', pdli.szDll, '" DLL');dliNotePreLoadLibrary:WriteLn('Starting to load "', pdli.szDll, '" DLL');dliNotePreGetProcAddress:WriteLn('Want to get address of "', ImportName(pdli.dlp), '" in "', pdli.szDll, '" DLL');dliNoteEndProcessing:WriteLn('Ended the delaay load session for "', pdli.szDll, '" DLL');dliFailLoadLibrary:WriteLn('Failed to load "', pdli.szDll, '" DLL');dliFailGetProcAddress:WriteLn('Failed to get proc address for "', ImportName(pdli.dlp), '" in "', pdli.szDll, '" DLL');end;{ Call the old hooks if they are not nil }{ This is recommended to do in case the old hook do further processing }if dliNotify in [dliFailLoadLibrary, dliFailGetProcAddress] thenbeginif Assigned(LOldNotifyHook) thenLOldFailureHook(dliNotify, pdli);end elsebeginif Assigned(LOldNotifyHook) thenLOldNotifyHook(dliNotify, pdli);end;Result := nil; end;begin{ Install new delayed loading hooks }LOldNotifyHook := SetDliNotifyHook2(MyDelayedLoadHook);LOldFailureHook := SetDliFailureHook2(MyDelayedLoadHook);{ Calling an existing delayed external routine }GetDesktopWindow;try{ Calling an unexisting delayed external routine in an existing library }GetFooBar;exceptend;try{ Calling an unexisting delayed external routine in an unexisting library }GetFooBarBar;exceptend;{ Reset the hooks }SetDliNotifyHook2(LOldNotifyHook);SetDliFailureHook2(LOldFailureHook);Readln; end.

?

SysInit.dliNotification

The following table lists the cases in which the registered hook is called by the delay load helper.

Value of?dliNotifyparameterDescription

dliNoteStartProcessing

Sent to a delayed-load notification hook when a delayed-load session is starting. Called before the library containing the delay loaded external procedure is processed. Used to bypass or notify helper only.

dliNotePreLoadLibrary

Sent before LoadLibrary is called, allowing a new HMODULE to be returned. Called before the library containing the delay loaded external procedure is loaded. Can override with the new HMODULE return value.

dliNotePreGetProcAddress

Sent before GetProcAddress, allowing for a new procedure address to be returned if desired. Called before the address of the delay loaded procedure is found. Can override with new HMODULE return value.

dliNoteEndProcessing

Sent to a delayed-load notification hook when all delayed-load processing completes. Cannot be bypassed except for raise or RaiseException.

dliFailLoadLibrary

Sent to a delayed-load failure hook when LoadLibrary fails; allows you to specify a different valid HMODULE handle.

dliFailGetProcAddress

Sent to a delay-load failure hook when GetProcAddress fails; allows you to replace the procedure address with the address of a valid procedure.

DelayLoadProc = recordfImportByName: LongBool;case Byte of0: (szProcName: _PAnsiChr);1: (dwOrdinal: LongWord);end;

?

Record that holds information for a procedure that is delay loaded.

The meaning of each field in the?DelayLoadProc?record is given in the following table.

?

FieldMeaning

szProcName

The name of the procedure.

dwOrdinal

The ordinal of the procedure.

advantages and disadvantages of delay load (LoadLibrary)

Some knowledgeable people posted the following wisdom about delay load. Archived here to share.?

The advantages are that dlls get loaded only when they are used,

and you can “statically” bind to an import that may not exist at runtime,

and as long as you are careful not to call it, the program will still work downlevel.?

The disadvantage is:

1)??????Some DLLs don’t work DelayLoaded (as mentioned in the limitations of LoadLibrary).?
In particular, any dll that uses __declspec(thread), or any dll that you want to import data from.

2)??????You can’t call any API that might be delay loaded in your DllMain (since you can’t call LoadLibrary during DllMain).?
Probably not a big deal since you’re generally not supposed to call any APIs in DllMain.

3)??????The DLLs in your process are now initialized in random order.?
There may be some orders that cause bizarre bugs.

4)??????In particular, if you “statically” bind to a dll, then your dll is uninitialized before that other dll.?
If you delayload, then you will be uninitialized after your delayloaded dlls.

5)??????Since DLLs may be loaded “late”, their preferred base address may be used already by stack or heap data,
resulting in a rebasing performance penalty that wouldn’t happen if the Dll was loaded at boot.

6)??????If the LoadLibrary fails for some reason (at the delay loading site), then your program just crashes.?
You can catch this exception, but it is difficult to recover from and definitely the API callsite that was expecting
to make a call into this delayed dll will have no direct way of detecting failures.?

The last one is the biggest burden. ?

It can mean random crashes when your app is under stress (because you’re out of memory to load that DLL).?

Unless your feature is specifically designed to deal with that DLL not loading

(and you’d have to put this code around every place where you call a delayed API), you run this random crash risk.?

Delay Loading definitely has its uses and its benefits, but the limitations means it is not correct to blindly delayload everything.

Only 1 is a real disadvantage.2,3,4,5 in most cases causes no problems.6 is a real advantage, because instead of receiving error in the loader you can get the error in the runtime and fix it. On the contrary, 6 is no advantage at all. A hard program crash is never a good situation to be in if it can be avoided. If you want the same behaviour, then throw your own exception or abort by some other easy to trace & debug mechanism when LoadLibrary fails. At least with that approach you can choose to fail gracefully.1 is a problem, but if you're doing that sort of thing you probably shouldn't be delay loading anyway. 3/4 is also a big problem when you have an API which then has an API built on top of it, the latter being delay loaded because it may or may not be there. In 6 you have the same code for both.LL+GetProcAddress:HMODULE h = LoadLibrary(...);if(!h) throw Exception;W/ DL:CallFunction() // If it fails you get exceptionRegular call:CallFuUnction() // If it fails in the loader your program cannot run at all !!3. You must not rely on dll load order. It is not good.4. Yes, this can cause problem in some times, I hope it won't cause problems for me :)

Delphi 2010 Delayed Dynamic Link Libraries

Delphi 2010 Delayed Dynamic Link Libraries
Traditionally, Dynamic Link Libraries (DLLs) can be loaded in two different ways:

implicit or explicit.

In this article, I’ll create a simple DLL, and show how this DLL can be loaded implicitly as well as explicitly.

I’ll then move to a new feature introduced with Delphi 2010:

the delayed loading of DLLs, which offers the best of both worlds and more, as we’ll see.

Example DLL
The example DLL should be as simple as possible,

yet introducing another nice feature that perhaps not all of the readers may know:

the concept of function overloading in DLLs, and how to export overloaded functions correctly.

The example I’m going to use her is a DLL with two “Add” methods,

one for adding integers, and one for adding doubles.

Since the function names are the same, we must decorate them with the overload keyword.

In order to export them, we must make sure each function is exported with a unique name,

so in case of the Add for doubles, I’ll export it by name “AddFloat”.?

The source code for the library eBob42 is as follows:

library eBob42;function Add(X,Y: Integer): Integer; overload; stdcall;beginResult := X + Yend;function Add(X,Y: Double): Double; overload; stdcall;beginResult := X + Yend;exportsAdd(X,Y: Integer) name 'Add',Add (X,Y: Double) name 'AddFloat';end.

When compiling this source code, we’ll end up with a eBob42.DLL that we can import and use in different ways:

implicit, explicit or with the new delayed technique, offered by Delphi 2010.

Implicit

The implicit import of functions from DLLs is the easiest way to use a DLL.

All you have to do is repeat the function definition, including the calling convention (plus overload when needed),

and add the “external” keyword plus the name of the DLL where the function can be found.

For an overloaded function, we should also include the name keyword again,

followed by the correct name under which the function was exported.

All in all, not very complex, and for the eBob42.DLL, the Implicit import unit could be implemented as follows:

unit eBob42Implicit;interfaceconstDLL = 'eBob42.DLL';function Add(X,Y: Integer): Integer; overload; stdcall external DLL;function Add(X,Y: Double): Double; overload; stdcall external DLL name 'AddFloat';implementationend.

?

The biggest disadvantage of using the implicit import of DLLs technique is the fact that you’ll get an error message when trying to load an application that requires a DLL, and that DLL cannot be found. In that situation, the application will be unable to start, so the error message is a fatal one, and without the DLL, the application itself is useless.

Explicit

The main alternative for implicit import is the explicit loading and import of functions from a DLL.

This takes more code, but it allows us to give a nice error message

when the DLL cannot be loaded and/or when a function from the DLL cannot be found,

without keeping the application itself from running.

So even without the DLL being present, the application can be used (albeit without the functionality from the DLL).?

As an example of an explicit import unit, where we explicitly need to load the DLL using

LoadLibrary and get a handle to the functions using GetProcAddress, is as follows:

unit eBob42Explicit;interfaceconstDLL = 'eBob42.DLL';varAdd: function(X,Y: Integer): Integer; stdcall = nil;AddFloat: function(X,Y: Double): Double; stdcall = nil;implementationusesWindows;vareBob42Handle: Cardinal;initializationeBob42Handle := LoadLibrary(DLL);if eBob42Handle <= 32 thenMessageBox(0,Error: could not load ' + DLL, 'Oops!', MB_OK)elsebeginAdd := GetProcAddress(eBob42Handle, 'Add');AddFloat := GetProcAddress(eBob42Handle, 'AddFloat')endfinalizationFreeLibrary(eBob42Handle)end.

?

Obviously, the unit eBob42Explicit is a lot bigger and complex than the simple unit eBob42Implicit.

And each additional function from the DLL will make this difference bigger,

because eBob42Implicit only needs to list the function (with the external keyword),

while eBob42Explicit needs to declare a function pointer and assign a value to that pointer using GetProcAddress.?

The biggest advantage of explicit importing is the fact that the application

will be able to load and start even if the DLL that we’re trying to use cannot be found (or loaded).

We’ll see an error message when the LoadLibrary or GetProcAddress fails, but the application itself will still run.?

The disadvantage is that the code for the explicit import unit is a lot more complex,

and when we call the imported functions through the function pointers,

we should check if the function pointers are actually assigned

(otherwise we might still get a run-time error or access violation).?

Although neither of these approaches appears perfect,

Delphi 2010 now supports a third method which combines the strength and best of both worlds, and then some.

The technique is known as delayed loading.

Delay Load
Delphi 2010 introduces a new keyword:?

delayed.

In fact, it’s so new that the online help, the wiki and even the syntax highlighter don’t know about it, yet.

The only source of information that I could find was the blog post of Allen Bauer of the Delphi R&D Team itself.?

The basic idea of the solution is the fact that the DLL will not be loaded right away (which is the case for implicit linking),

but only when needed.

So potentially “delayed”, and hence the name “delay loading”.?

The syntax of using the delayed approach is actually quite similar to the implicit import unit,

with the exception that we now add the delayed keyword to the function definition

(and since neither code insight and syntax highlighting seem to know about this new keyword,

you’ll have to trust on the compiler to tell you when it’s right:

after the name of the DLL, without semi-colon between the name of the DLL and the delayed keyword itself).?

unit eBob42Delayed;interfaceconstDLL = 'eBob42.DLL';function Add(X,Y: Integer): Integer; overload; stdcall external DLL delayed;function Add(X,Y: Double): Double; overload; stdcall external DLL name 'AddFloat' delayed;implementationend.

?

When compiling unit eBob42Delayed, you get two warnings about the delayed keyword,

telling you that the symbol DELAYED is specific to a platform.

Yeah right, that doesn’t matter to much to me to be honest.

What matters is that we now have the ease of implicit importing with the robustness of explicit importing.

The best of both worlds:

unit eBob42Delayed is as short as unit eBob42Implicit,

and yet the application will start normally even if the DLL cannot be found.?

There is one thing left to test:

imagine what would happen if we use the eBob42Delayed unit, and start the application

without the DLL being present (or found), and then call the function Add?

The good news is that the application can be started just fine, and will remain up-and-running.

The bad news is that the user will see a not very user-friendly error message, namely:

I can imagine that for the average user this error message will not be fully clear,

so the user may not know what the actual problem is.

Of course, we can catch this EExternalException in a try-except block,

but the problem is that we do not know if the error is caused by a missing DLL,

or perhaps by the function which was not found in the DLL

(for example if an incorrect version of the DLL was loaded with the correct name, but without the required function exported).

?

DelayedLoadHook

Based on a blog post from – again – Allen Bauer,

we could read that there is actually a way to handle the specific errors that can occur

when (delay) loading a DLL or obtaining a function pointer using GetProcAddress.

The delay loading itself is done in an old (but well-tested) delayhpl.c file from the C++RTL,

which offers the option to “hook” to the notification messages from this process

by defining a DelayedLoadHook function that we can install using the SetDliNotifyHook function.

The DelayedLoadHook function should be defined as follows (according to line 2392 of system.pas):

DelayedLoadHook = function (dliNotify: dliNotification; pdli: PDelayLoadInfo): Pointer; stdcall;

?The records dliNotification and PDelayLoadInfo are also interesting,

and contain the information we need to determine the nature of the notification (and possibly error).

?

Again a little snippet from system.pas:

dliNotification = (dliNoteStartProcessing, { used to bypass or note helper only }dliNotePreLoadLibrary, { called just before LoadLibrary, can }{ override w/ new HMODULE return val }dliNotePreGetProcAddress, { called just before GetProcAddress, can }{ override w/ new Proc address return }{ value }dliFailLoadLibrary, { failed to load library, fix it by }{ returning a valid HMODULE }dliFailGetProcAddress, { failed to get proc address, fix it by }{ returning a valid Proc address }dliNoteEndProcessing { called after all processing is done, }{ no bypass possible at this point }{ except by raise, or RaiseException });

?

Based on the value of dliFailLoadLibrary,?we can raise an exception to explain to the user in detail that a DLL could not be loaded.

And based on the value dliFailGetPRocAddress, we can tell the user that the DLL could be loaded,

but the specific function could not be found in this DLL.

In order to determine the name of the DLL and when needed the name of the function,

we should examine the DelayLoadInfo record, which is defined as follows:

DelayLoadInfo = recordcb: LongWord; { size of structure }pidd: PImgDelayDescr; { raw form of data (everything is there) }ppfn: Pointer; { points to address of function to load }szDll: PAnsiChar; { name of dll }dlp: TDelayLoadProc; { name or ordinal of procedure }hmodCur: HMODULE; { the hInstance of the library we have loaded }pfnCur: Pointer; { the actual function that will be called }dwLastError: LongWord; { error received (if an error notification) }end;

?

For the name of the DLL itself, we can use the field szDll,

and for the name of the function (or the value of the export index from the function in the DLL)
we have to look a little bit further (or deeper) to the dlp structure of type TDelayLoadProc.

The type DelayLoadProc in turn is defined in a variant record as follows:

DelayLoadProc = recordfImportByName: LongBool;case Byte of0: (szProcName: PAnsiChar);1: (dwOrdinal: LongWord);end;

If the variant record field fImportByName is true, then we should look at the szProcName field,

otherwise the value of the dwOrdinal field must be used

(in case the function was imported by index number instead of by name).?

With this information at our disposal, we can write a procedure DelayedHandlerHook (see listing 5)

with arguments dliNotification and PDelayLoadInfo,

and inside this procedure we can raise an exception with detailed information if the specific error situations have occurred.

DelayedHandler
For my own convenience, I’ve placed the procedure DelayedHandlerHook inside its own unit DelayedHandler,

making sure that the DelayedHandlerHook is installed by calling the SetDliFailureHook function

in the initialization section of the unit, and uninstalling it again in the finalization section again.

As a result, you only need to add this unit to the uses clause of any project that uses the “delayed” external references,

and needs to be able to raise specific exceptions for the situations

where the DLL could not be found (or loaded) or when a specific function (or index) could not be found in the DLL.?

The two specific exceptions are of type ELoadLibrary and EGetProcAddress and also defined in Listing 5:

unit DelayedHandler;interfaceusesSysUtils;typeELoadLibrary = class(Exception);EGetProcAddress = class(Exception);implementationfunction DelayedHandlerHook(dliNotify: dliNotification; pdli: PDelayLoadInfo): Pointer; stdcall;beginif dliNotify = dliFailLoadLibrary thenraise ELoadLibrary.Create('Could not load ' + pdli.szDll)elseif dliNotify = dliFailGetProcAddress thenif pdli.dlp.fImportByName thenraise EGetProcAddress.Create('Could not load ' + pdli.dlp.szProcName + ' from ' + pdli.szDll)elseraise EGetProcAddress.Create('Could not load index ' + IntToStr(pdli.dlp.dwOrdinal) + ' from ' + pdli.szDll)end;initializationSetDliFailureHook(DelayedHandlerHook);finalizationSetDliFailureHook(nil);end.

?

This time, when the DLL could not be found or loaded,

we’ll get a far more descriptive exception which can be displayed in a ShowMessage box as follows:

My final tests show that each time we call the (delay loaded) Add function,

the application tries to load the DLL (if not already loaded).

This means that if the DLL could not be found the first time this function was called,

then during the second attempt, it will again try to load the DLL.

And if we’ve found and for example installed the DLL in the meantime, then this means the second call will succeed!?

This is another, perhaps unexpected, advantage of the delayed loading approach compared to the explicit importing approach.

Unless we extend the explicit importing approach to also try to load the DLL

when we make a function call, the delay loading will be more robust and able to connect to a DLL even after the application has started.?

As final test, let’s see what happens if the DLL is present but we want to import and call a function with an incorrect name.

As a test, we should modify the eBob42Delayed unit for the Add Float function as follows:

function Add(X,Y: Double): Double; overload; stdcall external DLL name 'AddDouble' delayed; // was ‘AddFloat’

?

This will lead to a nice exception to inform us that the function AddDouble could not be found in the eBob42.DLL.

Note that the exception is displayed using a call to ShowMessage,?by our client code, inside a try-except block.

But you can use this technique also in web server application

(where you don’t want to use a ShowMessage) by handling the exception inside a try-except block in another way.

Summary

Where the implict import of DLLs is easy but not always very convenient or robust?(when the DLL is not present, the application won’t start),

and the explicit import of DLLs is robust but more complex (where you should also always check before calling a function pointer that this function pointer is actually assigned),

there the delayed loading technique of DLLs offers the best of both worlds.

The easy of declaration (with the additional delayed keyword) with the easy and robustness of use,

plus the ability to “connect” to the DLL at a later time, even after the application was started and the DLL wasn’t found the first time.

In combination with the unit DelayedHandler, for specific exception raising in case the DLL could not be found or loaded,

or a specific function was not found, we now have the ultimate way of importing and using DLLs from now on

(although this functionality is only supported by Delphi 2010).

References

Allen Bauer,?Procrastinators Unite… Eventually!?
Allen Bauer,?Exceptional Procrastination

?

Procrastinators Unite… Eventually!

We’re all taught at an early age to “Never put off until tomorrow that which can be done today.”

In general, that is wise advice. However there are some cases where you do want to wait

until the last possible moment to do (or not do) something.

In fact, that is one of the overall tenets of? Agile Programming;

delay decisions until the last possible moment

because you always know more about a problem tomorrow

than you do today and can make a better,?more informed decision.

But, I digress. I’m not here to talk about philosophies of life,

or to introduce another “agile methodology” or even about a new weight loss plan based on bacon, lard and cheese puffs.

How many of you have written this same bit of boilerplate code or something similar over and over again??

if OSVersion >= 5.0 then beginModule = LoadLibrary('kernel32.dll');if Module <> 0 thenbeginProc := GetProcAddress(Module, 'APICall');if Assigned(Proc) thenProc(Param1, Param2);end; end else{ gracefully fallback }What if you could just do this?if OSVersion >= 5.0 thenAPICall(Param1, Param2); else{ gracefully fallback }

The astute among you would immediately see that with previous Delphi releases,

the second form, while certainly preferable, at some point the call to “APICall”

would eventually have to effectively go through some bit of code similar to the first bit of code.

Normally, you would declare an external API reference like this:?

procedure APICall(Param1, Param2: Integer); stdcall; external 'kernel32.dll' name 'APICall';

?

?That will cause the linker to emit a external reference into the executable binary that is resolved?at load time.?

Therein lies the problem.

That is the situation that the first bit of code above was designed to avoid.

If APICall didn’t existing in ‘kernel32.dll’ at load time, the whole application would fail to load.

Game over.

Thanks for playing.

Now, what if you could write code similar the second block of code above?and?still declare your external API calls in a manner similar to above?

Starting with Delphi 2010, you can do exactly the scenario I describe.

To make the second code block work even if “APICall” isn’t available on the version of the OS on which your application is currently running,

we’ve introduced a new directive to be used only in the above context,?delayed;

procedure APICall(Param1, Param2: Integer); stdcall; external 'kernel32.dll' name 'APICall' delayed;

Simply put, by adding the delayed directive, that instructs the linker to generate the external API reference differently in the executable binary.

Now Delphi’s RTL will take care of all that ugly “late-binding” boilerplate code for you.

Rather than generating the import in the normal “Imports” section of the executable’s PE file,

it is generated into the “Delayed Imports” section following the published PE spec.

This also requires that the RTL now has a generic function that does the proper lookups

and binds the API whenever it is called the first time.

Subsequent calls are just as fast as a normal import.

This is different than similar functionality available in ILink32 from C++Builder

wherein you can only specify an entire dll in which?all?references are delay loaded.

Also, in C++ you cannot specify kernel32.dll or even ntdll.dll to be delay loaded,

since the very startup of any application or dll requires them to already be loaded.

In Delphi you can, since it is on an API-by-API basis.

The intent of this feature was to make managing all the new APIs

from Windows Vista and now Windows 7 much easier without having to continuously

and manually write all the delay loaded boilerplate code.

Throughout VCL, we can simply make runtime decisions on

which APIs to call without always going through those manually coded “thunks.”

They are now simply handled by the compiler/linker

and the source code barely reveals the fact that something is late-bound.

In a future release, we are considering adding

both the API-by-API capability to C++Builder?and?

a way to specify an entire dll to be late-bound in Delphi.

Exceptional Procrastination

I kept putting this post off… ok, ok… that was a really bad pun…

Seems there was a little bit of concern about my?

last post regarding the new ‘delayed’ directive.?

Christian Wimmer had a few critiques?

regarding the implementation and how the exception

that was raised was an EExternalException with an obscure exception code.

There is a simple explanation for this.

The delay load helper functions were taken directly from the C++Builder RTL.

By that I mean, the delayhlp.c file gets built to a .obj file

by the C++ compiler and then directly linked into the Delphi System unit.

There were several key reasons for this.

?

?

The first of which was the code was already written, has been in many versions of C++Builder RTL

(including back in the old Borland C++ days) and has been extensively tested.

?

Another reason is that in order for Delphi and C++Builder to “play-nice,”

when a Delphi unit is linked in C++Builder that contains a reference to a delay load import,

ILink32 takes over the duties of generating the proper delay load functionality into the PE file.

?

So the C++RTL version of delayhlp.c is what is used.

?

In order to things to remain consistent, this is the route taken.

Had there been two delay-load helper functions in the case of a C++Builder application,

then any existing C++ code that used the delay load hooks would only work on other C++ code and vice-versa.

?

Fear not, all is not lost.

To satisfy our good friend, Christian’s request, here is a unit that you can use to generate nice,

unique Delphi specific exceptions.

This is accomplished by leveraging the ability for the delayhlp.c code to be “hooked.”

This code also demonstrates another new Delphi language feature,

class constructors and destructors.

I will describe them in better detail in a subsequent post.

If you never reference any of the declared exception types in this unit,

the hook is not installed and the normal EExternalException is raised.

Presumably you would use this unit for the purpose of actually catching the exceptions

and doing something interesting with them.

Another thing to note is that you should also be able to add this unit to a C++Builder application

and it work for any delay-load functions done in the existing way for C++

and any Delphi units that reference Delphi imports with the delayed directive.

unit DelayExcept;interfaceuses SysUtils;typeEDliException = class(Exception)privateclass constructor Create;class destructor Destroy;end;EDliLoadLibraryExeception = class(EDliException)privateFDllName: string;publicconstructor Create(const ADllName: string); overload;property DllName: string read FDllName;end;EDliGetProcAddressException = class(EDliException)privateFDllName: string;FExportName: string;publicconstructor Create(const ADllName, AExportName: string); overload;constructor Create(const ADllName: string; AOrdinal: LongWord); overload;property DllName: string read FDllName;property ExportName: string read FExportName;end;implementation{ EDliLoadLibraryExeception }constructor EDliLoadLibraryExeception.Create(const ADllName: string); begininherited Create(Format('Unable to load ''%s''', [ADllName]));FDllName := ADllName; end;{ EDliGetProcAddressException }constructor EDliGetProcAddressException.Create(const ADllName, AExportName: string); begininherited Create(Format('Unable to locate export name ''%s'' in ''%s''', [AExportName, ADllName]));FDllName := ADllName;FExportName := AExportName; end;constructor EDliGetProcAddressException.Create(const ADllName: string; AOrdinal: LongWord); begininherited Create(Format('Unable to locate export ordinal ''%d'' in ''%s''', [AOrdinal, ADllName]));FDllName := ADllName;FExportName := IntToStr(AOrdinal); end;function DelayLoadFailureHook(dliNotify: dliNotification; pdli: PDelayLoadInfo): Pointer; stdcall; beginResult := nil;if dliNotify = dliFailLoadLibrary thenraise EDliLoadLibraryExeception.Create(pdli.szDll);if dliNotify = dliFailGetProcAddress thenif pdli.dlp.fImportByName thenraise EDliGetProcAddressException.Create(pdli.szDll, pdli.dlp.szProcName)elseraise EDliGetProcAddressException.Create(pdli.szDll, pdli.dlp.dwOrdinal); end;{ EDliException }class constructor EDliException.Create; beginSetDliFailureHook(DelayLoadFailureHook); end;class destructor EDliException.Destroy; beginSetDliFailureHook(nil); end;end.

?

總結

以上是生活随笔為你收集整理的Delphi DLL制作和加载 Static, Dynamic, Delayed 以及 Shared-Memory Manager的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

午夜福利试看120秒体验区 | 精品成在人线av无码免费看 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 黑人粗大猛烈进出高潮视频 | 久久久久se色偷偷亚洲精品av | 国产福利视频一区二区 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 欧美国产亚洲日韩在线二区 | 欧美激情综合亚洲一二区 | 九九久久精品国产免费看小说 | 国产人妻精品午夜福利免费 | 无码国产色欲xxxxx视频 | 荫蒂被男人添的好舒服爽免费视频 | 国产办公室秘书无码精品99 | 亚洲人成影院在线观看 | 久久午夜夜伦鲁鲁片无码免费 | 亚洲一区二区三区无码久久 | 色综合久久88色综合天天 | 国产人成高清在线视频99最全资源 | 天天摸天天碰天天添 | 欧美成人高清在线播放 | 国产无套粉嫩白浆在线 | 亚欧洲精品在线视频免费观看 | 色妞www精品免费视频 | 巨爆乳无码视频在线观看 | 99er热精品视频 | 欧美性猛交内射兽交老熟妇 | 国产成人精品一区二区在线小狼 | 天天综合网天天综合色 | 日韩人妻无码一区二区三区久久99 | 国产一区二区三区日韩精品 | 色婷婷av一区二区三区之红樱桃 | 精品国产一区二区三区av 性色 | 亚洲 a v无 码免 费 成 人 a v | 午夜无码人妻av大片色欲 | 狠狠色噜噜狠狠狠7777奇米 | 双乳奶水饱满少妇呻吟 | 国产精品沙发午睡系列 | 牲欲强的熟妇农村老妇女视频 | 国产情侣作爱视频免费观看 | 欧美日韩一区二区综合 | 国产成人无码午夜视频在线观看 | 少妇被黑人到高潮喷出白浆 | 色情久久久av熟女人妻网站 | 精品厕所偷拍各类美女tp嘘嘘 | 大乳丰满人妻中文字幕日本 | 无遮挡啪啪摇乳动态图 | 国产无遮挡又黄又爽免费视频 | 国产精品久久久久久无码 | 亚洲自偷自偷在线制服 | 最近的中文字幕在线看视频 | 特级做a爰片毛片免费69 | 午夜成人1000部免费视频 | 99精品无人区乱码1区2区3区 | 亚洲日韩av一区二区三区中文 | 97色伦图片97综合影院 | 免费中文字幕日韩欧美 | 日本精品人妻无码77777 天堂一区人妻无码 | 国产手机在线αⅴ片无码观看 | 国产精品亚洲lv粉色 | 亚洲乱码日产精品bd | 亚洲精品久久久久久久久久久 | 久久久久久亚洲精品a片成人 | 亚洲精品国产精品乱码不卡 | 狠狠综合久久久久综合网 | 亚洲午夜无码久久 | 色五月五月丁香亚洲综合网 | 日产精品高潮呻吟av久久 | 亚洲一区二区观看播放 | 成人综合网亚洲伊人 | 国产肉丝袜在线观看 | 青春草在线视频免费观看 | 无码人妻出轨黑人中文字幕 | 成人一在线视频日韩国产 | 国产精品亚洲а∨无码播放麻豆 | 亚洲阿v天堂在线 | 最近中文2019字幕第二页 | 人妻夜夜爽天天爽三区 | 精品亚洲成av人在线观看 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 亚洲色www成人永久网址 | 人妻少妇精品无码专区二区 | 亚洲国产精品无码一区二区三区 | 国产莉萝无码av在线播放 | 国产午夜无码视频在线观看 | 精品久久久中文字幕人妻 | 免费无码的av片在线观看 | 无码帝国www无码专区色综合 | 日日摸天天摸爽爽狠狠97 | 精品熟女少妇av免费观看 | 最新版天堂资源中文官网 | 国产精品永久免费视频 | 少妇人妻偷人精品无码视频 | 好爽又高潮了毛片免费下载 | 一区二区三区乱码在线 | 欧洲 | 在线观看国产一区二区三区 | 国产真人无遮挡作爱免费视频 | 无码av最新清无码专区吞精 | 乱人伦人妻中文字幕无码久久网 | 国产亚洲视频中文字幕97精品 | 国产午夜亚洲精品不卡下载 | 国产卡一卡二卡三 | 少妇久久久久久人妻无码 | 色婷婷欧美在线播放内射 | 初尝人妻少妇中文字幕 | 亚洲日本一区二区三区在线 | 日韩精品无码一区二区中文字幕 | 亚洲熟妇色xxxxx欧美老妇y | 黑人粗大猛烈进出高潮视频 | 亚洲七七久久桃花影院 | 波多野结衣av一区二区全免费观看 | 亚洲熟妇色xxxxx欧美老妇 | 亚洲娇小与黑人巨大交 | 亚洲国产午夜精品理论片 | 帮老师解开蕾丝奶罩吸乳网站 | √8天堂资源地址中文在线 | 国产口爆吞精在线视频 | 高潮喷水的毛片 | 日韩精品一区二区av在线 | 久久精品女人天堂av免费观看 | 久久久精品成人免费观看 | 国语精品一区二区三区 | 国产莉萝无码av在线播放 | 亚洲色成人中文字幕网站 | 无码人妻av免费一区二区三区 | 久久精品成人欧美大片 | 中文字幕无码日韩欧毛 | 天海翼激烈高潮到腰振不止 | 久久久久99精品成人片 | 任你躁在线精品免费 | 免费播放一区二区三区 | 亚洲精品午夜国产va久久成人 | 少妇久久久久久人妻无码 | 久久国产精品_国产精品 | 色综合久久久无码中文字幕 | 国产精品久久久久久久9999 | 国产精品嫩草久久久久 | 国产高清av在线播放 | 久久精品国产精品国产精品污 | 大肉大捧一进一出好爽视频 | 中文字幕日产无线码一区 | 美女扒开屁股让男人桶 | 成 人影片 免费观看 | 好屌草这里只有精品 | 国产精品va在线播放 | 日本欧美一区二区三区乱码 | 麻豆国产丝袜白领秘书在线观看 | 亚洲va中文字幕无码久久不卡 | 性欧美疯狂xxxxbbbb | 无码人妻av免费一区二区三区 | 成年女人永久免费看片 | 人妻少妇精品视频专区 | 精品国产av色一区二区深夜久久 | av在线亚洲欧洲日产一区二区 | 亚洲成av人片天堂网无码】 | a国产一区二区免费入口 | 中文字幕 亚洲精品 第1页 | а天堂中文在线官网 | 亚洲精品一区二区三区婷婷月 | 性做久久久久久久免费看 | 亚洲精品午夜国产va久久成人 | 亚洲国产精品无码久久久久高潮 | 性做久久久久久久免费看 | 97久久国产亚洲精品超碰热 | 国产suv精品一区二区五 | 99久久人妻精品免费二区 | 美女极度色诱视频国产 | 久久精品中文字幕大胸 | 日本在线高清不卡免费播放 | а天堂中文在线官网 | 亚洲中文字幕无码中文字在线 | 三上悠亚人妻中文字幕在线 | 偷窥村妇洗澡毛毛多 | 日日鲁鲁鲁夜夜爽爽狠狠 | 国内精品九九久久久精品 | 亚洲人成人无码网www国产 | 男女下面进入的视频免费午夜 | 日韩人妻无码一区二区三区久久99 | 日韩视频 中文字幕 视频一区 | 日本丰满护士爆乳xxxx | 精品无码成人片一区二区98 | 国产后入清纯学生妹 | 亚洲成av人片在线观看无码不卡 | 成人毛片一区二区 | 亚无码乱人伦一区二区 | 亚洲啪av永久无码精品放毛片 | 亚洲中文字幕乱码av波多ji | 亚洲狠狠色丁香婷婷综合 | 午夜时刻免费入口 | 一区二区三区乱码在线 | 欧洲 | 日韩视频 中文字幕 视频一区 | 激情综合激情五月俺也去 | 装睡被陌生人摸出水好爽 | 亚洲综合在线一区二区三区 | 国产国语老龄妇女a片 | 亚洲精品成人av在线 | 无码帝国www无码专区色综合 | 国产真人无遮挡作爱免费视频 | 国产口爆吞精在线视频 | 成人无码精品一区二区三区 | 国产又爽又黄又刺激的视频 | 香蕉久久久久久av成人 | 国产人成高清在线视频99最全资源 | 特黄特色大片免费播放器图片 | 成年美女黄网站色大免费视频 | 国产精品va在线播放 | 娇妻被黑人粗大高潮白浆 | 日本欧美一区二区三区乱码 | 久久精品中文字幕大胸 | 高清国产亚洲精品自在久久 | 久久久久se色偷偷亚洲精品av | 久激情内射婷内射蜜桃人妖 | 国产免费久久精品国产传媒 | 国产成人无码av片在线观看不卡 | 99久久亚洲精品无码毛片 | 国产特级毛片aaaaaaa高清 | 人妻少妇精品无码专区二区 | 国内精品久久久久久中文字幕 | 成人免费无码大片a毛片 | 国产精品国产自线拍免费软件 | 欧美精品免费观看二区 | 欧洲精品码一区二区三区免费看 | av无码不卡在线观看免费 | 久久久久人妻一区精品色欧美 | 久久综合九色综合欧美狠狠 | 亚洲精品综合一区二区三区在线 | 兔费看少妇性l交大片免费 | 日本免费一区二区三区最新 | 亚洲小说图区综合在线 | 久久99精品国产麻豆蜜芽 | 久久久中文字幕日本无吗 | 亚洲欧美精品aaaaaa片 | 精品国产乱码久久久久乱码 | 亚洲成av人片在线观看无码不卡 | 国产人妻大战黑人第1集 | 国产精品美女久久久网av | 精品偷自拍另类在线观看 | 色一情一乱一伦一视频免费看 | 99精品久久毛片a片 | 无码国产色欲xxxxx视频 | 女人高潮内射99精品 | 伊人久久大香线焦av综合影院 | 丰满少妇熟乱xxxxx视频 | 久久人人爽人人爽人人片av高清 | 国内老熟妇对白xxxxhd | 国产精品久久久久久无码 | 久久精品国产一区二区三区肥胖 | 青青青手机频在线观看 | 国产亚洲精品久久久久久大师 | 亚洲国产精品美女久久久久 | 亚洲天堂2017无码中文 | 国产亚洲精品久久久久久久 | 少妇无套内谢久久久久 | av人摸人人人澡人人超碰下载 | √天堂中文官网8在线 | 精品无码av一区二区三区 | 亚洲熟妇色xxxxx欧美老妇y | 国产成人无码一二三区视频 | 亚洲一区二区三区国产精华液 | 午夜福利一区二区三区在线观看 | 无码人妻出轨黑人中文字幕 | 亚洲国产精品久久久天堂 | 久久精品无码一区二区三区 | 亚欧洲精品在线视频免费观看 | 久久综合狠狠综合久久综合88 | 免费无码的av片在线观看 | 网友自拍区视频精品 | 久久人人爽人人人人片 | 蜜臀aⅴ国产精品久久久国产老师 | 欧美日韩综合一区二区三区 | 麻豆蜜桃av蜜臀av色欲av | 色 综合 欧美 亚洲 国产 | 亚洲成a人片在线观看无码 | 日产国产精品亚洲系列 | 熟女少妇在线视频播放 | 亚洲性无码av中文字幕 | 亚洲精品一区二区三区四区五区 | 好屌草这里只有精品 | 男女性色大片免费网站 | 亚洲人成影院在线观看 | 青青青手机频在线观看 | 日本www一道久久久免费榴莲 | 图片小说视频一区二区 | 国产精品亚洲五月天高清 | 精品国产一区av天美传媒 | 日日摸日日碰夜夜爽av | 久久综合给合久久狠狠狠97色 | 狠狠噜狠狠狠狠丁香五月 | 7777奇米四色成人眼影 | 久久精品国产99久久6动漫 | 中文字幕乱码人妻二区三区 | 伊人久久婷婷五月综合97色 | 久久精品中文闷骚内射 | 高中生自慰www网站 | 亚洲阿v天堂在线 | 天堂а√在线地址中文在线 | 男女下面进入的视频免费午夜 | 日日麻批免费40分钟无码 | 久久精品国产精品国产精品污 | 精品无码一区二区三区爱欲 | 网友自拍区视频精品 | 黑人粗大猛烈进出高潮视频 | 精品无码av一区二区三区 | 日韩精品无码免费一区二区三区 | 欧美性生交xxxxx久久久 | 成人性做爰aaa片免费看不忠 | 鲁大师影院在线观看 | 天天爽夜夜爽夜夜爽 | 亚洲娇小与黑人巨大交 | 无人区乱码一区二区三区 | 欧美黑人性暴力猛交喷水 | 色综合久久久无码中文字幕 | 色偷偷人人澡人人爽人人模 | 天堂久久天堂av色综合 | 日本xxxx色视频在线观看免费 | 少妇被粗大的猛进出69影院 | 亚洲第一网站男人都懂 | 久9re热视频这里只有精品 | 欧美人与物videos另类 | 亚洲a无码综合a国产av中文 | 久久综合网欧美色妞网 | 午夜福利不卡在线视频 | 蜜臀av在线播放 久久综合激激的五月天 | 亚洲成av人综合在线观看 | 久久国语露脸国产精品电影 | 日本www一道久久久免费榴莲 | 呦交小u女精品视频 | 国产精品沙发午睡系列 | 97久久超碰中文字幕 | 国产精品第一区揄拍无码 | 亚洲欧美日韩综合久久久 | 亚洲日韩av一区二区三区中文 | 日韩av无码一区二区三区不卡 | 大乳丰满人妻中文字幕日本 | 亚欧洲精品在线视频免费观看 | 国产精品久久精品三级 | 成人免费视频一区二区 | www国产精品内射老师 | 成人免费视频视频在线观看 免费 | 成人亚洲精品久久久久软件 | 国产在线精品一区二区高清不卡 | 国产精品久久国产精品99 | 天堂久久天堂av色综合 | av无码久久久久不卡免费网站 | 国产精品久久久av久久久 | 中文字幕av无码一区二区三区电影 | 丰满少妇人妻久久久久久 | 精品aⅴ一区二区三区 | 中文亚洲成a人片在线观看 | 国产精品内射视频免费 | 欧美日韩色另类综合 | 免费人成在线观看网站 | 国产成人av免费观看 | 无码人妻少妇伦在线电影 | 国产一区二区三区日韩精品 | 久久久久久亚洲精品a片成人 | 久久婷婷五月综合色国产香蕉 | 天天燥日日燥 | 亚洲码国产精品高潮在线 | 国产无遮挡吃胸膜奶免费看 | 国产色视频一区二区三区 | 高清无码午夜福利视频 | 日韩人妻系列无码专区 | 国产精品va在线播放 | 欧美日本免费一区二区三区 | 成在人线av无码免费 | 国产特级毛片aaaaaa高潮流水 | 亚洲熟妇色xxxxx亚洲 | 国产精品久久久久久久影院 | 国产成人综合在线女婷五月99播放 | 老熟女重囗味hdxx69 | 九一九色国产 | 国产精品va在线观看无码 | 女人被男人躁得好爽免费视频 | v一区无码内射国产 | 又大又黄又粗又爽的免费视频 | 久久99久久99精品中文字幕 | 久久久久免费看成人影片 | 亚洲精品一区二区三区大桥未久 | 亚洲中文字幕在线无码一区二区 | 日本丰满熟妇videos | 精品久久综合1区2区3区激情 | 国产在线精品一区二区三区直播 | 亚洲毛片av日韩av无码 | 亚洲码国产精品高潮在线 | 中文字幕av日韩精品一区二区 | 97精品国产97久久久久久免费 | 亚洲日韩av片在线观看 | 鲁一鲁av2019在线 | 无码国产乱人伦偷精品视频 | 亚洲 另类 在线 欧美 制服 | 97久久国产亚洲精品超碰热 | 亚洲人成无码网www | 亚洲日韩一区二区 | 亚洲成av人片在线观看无码不卡 | 东京无码熟妇人妻av在线网址 | 国产亲子乱弄免费视频 | 日本丰满熟妇videos | 亚洲精品鲁一鲁一区二区三区 | 国产亚av手机在线观看 | 国产精品久久久久久久9999 | 国产av一区二区精品久久凹凸 | 精品人妻人人做人人爽 | 自拍偷自拍亚洲精品10p | 亚洲の无码国产の无码影院 | 亚洲欧美国产精品专区久久 | 国产97色在线 | 免 | aa片在线观看视频在线播放 | 免费网站看v片在线18禁无码 | 一本色道久久综合狠狠躁 | 国产香蕉尹人综合在线观看 | 久久精品99久久香蕉国产色戒 | 婷婷色婷婷开心五月四房播播 | 亚洲第一无码av无码专区 | 免费无码的av片在线观看 | 久久国产自偷自偷免费一区调 | 亚洲成a人片在线观看无码 | 国产免费久久久久久无码 | 久久国产精品偷任你爽任你 | 精品人妻av区 | 又紧又大又爽精品一区二区 | 在线播放免费人成毛片乱码 | 日本高清一区免费中文视频 | 亚洲熟悉妇女xxx妇女av | 亚洲日韩av片在线观看 | 99久久亚洲精品无码毛片 | 国产一区二区三区四区五区加勒比 | 国产精品久久久久久无码 | 国产精品资源一区二区 | 国产成人人人97超碰超爽8 | 亚洲中文字幕无码中文字在线 | 激情人妻另类人妻伦 | 中文字幕 亚洲精品 第1页 | 久久午夜无码鲁丝片午夜精品 | 人人妻人人澡人人爽人人精品浪潮 | 国产午夜手机精彩视频 | 蜜桃av抽搐高潮一区二区 | 一本久久a久久精品亚洲 | 久久97精品久久久久久久不卡 | 成 人 网 站国产免费观看 | 午夜精品久久久久久久久 | 国产三级精品三级男人的天堂 | 欧美日本精品一区二区三区 | 真人与拘做受免费视频 | 久久亚洲a片com人成 | 国产电影无码午夜在线播放 | 国产精品美女久久久久av爽李琼 | 精品厕所偷拍各类美女tp嘘嘘 | 熟女俱乐部五十路六十路av | 成人综合网亚洲伊人 | 97se亚洲精品一区 | 亚洲精品久久久久久一区二区 | 国产成人精品三级麻豆 | 黑人巨大精品欧美一区二区 | 欧美性生交活xxxxxdddd | 国产成人无码一二三区视频 | 成人亚洲精品久久久久软件 | 无码播放一区二区三区 | 国产精品亚洲五月天高清 | 欧美三级不卡在线观看 | 久久国产精品萌白酱免费 | 玩弄人妻少妇500系列视频 | 国产精品久久久久久亚洲毛片 | 清纯唯美经典一区二区 | 日本一卡二卡不卡视频查询 | 亚洲中文字幕在线无码一区二区 | 亚洲七七久久桃花影院 | 天堂а√在线中文在线 | 国产精品人人妻人人爽 | 国产高潮视频在线观看 | 国产 精品 自在自线 | 色一情一乱一伦一视频免费看 | 狠狠色色综合网站 | 亚洲综合精品香蕉久久网 | 精品国产乱码久久久久乱码 | 暴力强奷在线播放无码 | 天天摸天天透天天添 | 99久久久无码国产aaa精品 | 性做久久久久久久免费看 | 久久亚洲中文字幕精品一区 | 亚洲国产欧美日韩精品一区二区三区 | 麻豆国产人妻欲求不满谁演的 | 大肉大捧一进一出视频出来呀 | 蜜桃av抽搐高潮一区二区 | 欧美freesex黑人又粗又大 | 亚洲无人区一区二区三区 | 欧美老人巨大xxxx做受 | 九月婷婷人人澡人人添人人爽 | 精品一区二区三区无码免费视频 | 日本护士xxxxhd少妇 | 久久久成人毛片无码 | 欧美变态另类xxxx | 国产精品人人爽人人做我的可爱 | 国产精品二区一区二区aⅴ污介绍 | 久久99精品久久久久久 | 欧美老妇交乱视频在线观看 | 免费无码一区二区三区蜜桃大 | 久久精品中文字幕大胸 | 无码人妻出轨黑人中文字幕 | 国产超碰人人爽人人做人人添 | 国产精品无码一区二区桃花视频 | 成人亚洲精品久久久久软件 | 日韩av激情在线观看 | 欧美xxxx黑人又粗又长 | 国产农村妇女高潮大叫 | 黑森林福利视频导航 | 亚洲人成网站免费播放 | 无码人妻精品一区二区三区不卡 | 99久久人妻精品免费二区 | 丰满诱人的人妻3 | 国产又粗又硬又大爽黄老大爷视 | www国产亚洲精品久久网站 | 久在线观看福利视频 | 亚洲成a人片在线观看无码3d | 中文无码成人免费视频在线观看 | 粉嫩少妇内射浓精videos | 人妻夜夜爽天天爽三区 | 国产精品免费大片 | 精品无码国产一区二区三区av | 久久国产精品二国产精品 | 国产精品久久久av久久久 | 麻豆md0077饥渴少妇 | 97夜夜澡人人爽人人喊中国片 | 亚洲 a v无 码免 费 成 人 a v | 中文字幕乱码亚洲无线三区 | 男女作爱免费网站 | 一本一道久久综合久久 | 亚洲中文字幕在线无码一区二区 | 国产极品美女高潮无套在线观看 | 日韩人妻少妇一区二区三区 | 5858s亚洲色大成网站www | 国产在线aaa片一区二区99 | 中文无码精品a∨在线观看不卡 | 亚洲国产精品无码久久久久高潮 | 国产精品亚洲综合色区韩国 | 久久视频在线观看精品 | 97无码免费人妻超级碰碰夜夜 | 国产欧美精品一区二区三区 | 欧美日本免费一区二区三区 | 青青久在线视频免费观看 | 蜜桃无码一区二区三区 | 久9re热视频这里只有精品 | 最新国产麻豆aⅴ精品无码 | 色婷婷欧美在线播放内射 | 九九久久精品国产免费看小说 | 日本va欧美va欧美va精品 | 欧美人与善在线com | 免费无码的av片在线观看 | 最新版天堂资源中文官网 | 免费男性肉肉影院 | 中文字幕亚洲情99在线 | 我要看www免费看插插视频 | 久久久久99精品国产片 | 国产疯狂伦交大片 | 漂亮人妻洗澡被公强 日日躁 | 亚洲欧美综合区丁香五月小说 | 国产色精品久久人妻 | 人妻互换免费中文字幕 | 国产一区二区三区四区五区加勒比 | 女人被男人爽到呻吟的视频 | 国内精品久久久久久中文字幕 | 免费乱码人妻系列无码专区 | 日日躁夜夜躁狠狠躁 | 亚洲一区av无码专区在线观看 | 国产精品无码一区二区桃花视频 | 两性色午夜视频免费播放 | 十八禁视频网站在线观看 | 国产片av国语在线观看 | 国产精品-区区久久久狼 | 日韩精品a片一区二区三区妖精 | 美女张开腿让人桶 | 久久zyz资源站无码中文动漫 | 成人欧美一区二区三区黑人免费 | 日韩亚洲欧美中文高清在线 | 日本饥渴人妻欲求不满 | 精品午夜福利在线观看 | 亚洲色大成网站www国产 | 午夜丰满少妇性开放视频 | 国产av人人夜夜澡人人爽麻豆 | 欧美真人作爱免费视频 | 中文字幕无码人妻少妇免费 | 精品无码国产一区二区三区av | 精品无码成人片一区二区98 | 国产精品无码一区二区三区不卡 | 97精品人妻一区二区三区香蕉 | 亚洲热妇无码av在线播放 | 国产亚洲精品久久久闺蜜 | 无码av中文字幕免费放 | 亚洲伊人久久精品影院 | 在线观看国产午夜福利片 | 亚洲乱码日产精品bd | 亚洲精品无码国产 | 丁香花在线影院观看在线播放 | 在线欧美精品一区二区三区 | 久久精品国产亚洲精品 | 精品国产福利一区二区 | 老熟妇乱子伦牲交视频 | 永久免费观看国产裸体美女 | 亚洲国产精品一区二区第一页 | 少妇人妻偷人精品无码视频 | 国产精品理论片在线观看 | 日本一区二区三区免费播放 | 午夜精品久久久久久久 | 扒开双腿吃奶呻吟做受视频 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产香蕉尹人视频在线 | 嫩b人妻精品一区二区三区 | 久久亚洲中文字幕无码 | 国产尤物精品视频 | 无码播放一区二区三区 | 国产精品久久久 | 久久久精品成人免费观看 | 丰满少妇熟乱xxxxx视频 | 亚洲区欧美区综合区自拍区 | 免费人成在线观看网站 | 日韩亚洲欧美中文高清在线 | 免费人成网站视频在线观看 | 色欲人妻aaaaaaa无码 | 亚洲一区二区三区偷拍女厕 | 亚洲日本va中文字幕 | 久久无码专区国产精品s | 四十如虎的丰满熟妇啪啪 | 98国产精品综合一区二区三区 | 亲嘴扒胸摸屁股激烈网站 | 国产成人无码区免费内射一片色欲 | 美女毛片一区二区三区四区 | 国产精品欧美成人 | 俺去俺来也在线www色官网 | 日本熟妇人妻xxxxx人hd | 久热国产vs视频在线观看 | 最新国产乱人伦偷精品免费网站 | 成人亚洲精品久久久久软件 | aⅴ亚洲 日韩 色 图网站 播放 | 久久久久久a亚洲欧洲av冫 | 日韩精品成人一区二区三区 | 久久久久久亚洲精品a片成人 | 青草视频在线播放 | 红桃av一区二区三区在线无码av | 日韩精品无码一区二区中文字幕 | 男女猛烈xx00免费视频试看 | 欧美zoozzooz性欧美 | 精品国产国产综合精品 | 成人影院yy111111在线观看 | 漂亮人妻洗澡被公强 日日躁 | 精品久久久久久人妻无码中文字幕 | 亚洲一区二区三区无码久久 | 亚洲精品一区二区三区四区五区 | 九九在线中文字幕无码 | 国产又爽又黄又刺激的视频 | 中文字幕中文有码在线 | 未满成年国产在线观看 | 成人欧美一区二区三区 | 中文毛片无遮挡高清免费 | 2020最新国产自产精品 | 国产美女极度色诱视频www | 76少妇精品导航 | 樱花草在线社区www | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 亚洲综合精品香蕉久久网 | 激情内射亚州一区二区三区爱妻 | 亚洲の无码国产の无码影院 | 激情人妻另类人妻伦 | 色综合久久久无码中文字幕 | 国产极品美女高潮无套在线观看 | 风流少妇按摩来高潮 | 婷婷色婷婷开心五月四房播播 | 国产精品爱久久久久久久 | 在线欧美精品一区二区三区 | 精品成在人线av无码免费看 | 激情内射亚州一区二区三区爱妻 | 久久99精品久久久久久动态图 | 国产午夜亚洲精品不卡下载 | 小泽玛莉亚一区二区视频在线 | 无码人妻出轨黑人中文字幕 | 国产激情无码一区二区app | 性欧美大战久久久久久久 | 成人片黄网站色大片免费观看 | 国产又爽又猛又粗的视频a片 | 国产sm调教视频在线观看 | 中文无码成人免费视频在线观看 | 丰满人妻被黑人猛烈进入 | 国产精品第一区揄拍无码 | 久久久国产一区二区三区 | 妺妺窝人体色www婷婷 | 人人澡人人妻人人爽人人蜜桃 | 精品 日韩 国产 欧美 视频 | 亚洲欧美中文字幕5发布 | 欧美成人家庭影院 | 中文字幕无线码免费人妻 | 无码av岛国片在线播放 | 成人欧美一区二区三区黑人 | 国产内射爽爽大片视频社区在线 | 无码一区二区三区在线 | 性欧美疯狂xxxxbbbb | 国内少妇偷人精品视频 | 人人澡人人妻人人爽人人蜜桃 | 亚洲国产精品一区二区美利坚 | 国产极品视觉盛宴 | 国产真人无遮挡作爱免费视频 | 成人片黄网站色大片免费观看 | 欧美老人巨大xxxx做受 | 午夜时刻免费入口 | 漂亮人妻洗澡被公强 日日躁 | 国产午夜无码视频在线观看 | 乱人伦中文视频在线观看 | 国产综合色产在线精品 | 一本久道久久综合狠狠爱 | 成人三级无码视频在线观看 | 国产熟妇高潮叫床视频播放 | 欧美老妇与禽交 | 久久久婷婷五月亚洲97号色 | 丰腴饱满的极品熟妇 | 97精品人妻一区二区三区香蕉 | 亚洲va中文字幕无码久久不卡 | 国产成人亚洲综合无码 | 理论片87福利理论电影 | 女人和拘做爰正片视频 | 男人扒开女人内裤强吻桶进去 | 少妇无码av无码专区在线观看 | 日本欧美一区二区三区乱码 | 久久亚洲精品中文字幕无男同 | 最近的中文字幕在线看视频 | 蜜桃无码一区二区三区 | 性生交大片免费看女人按摩摩 | 2020最新国产自产精品 | 野狼第一精品社区 | 最近免费中文字幕中文高清百度 | 国产精品无码成人午夜电影 | 2019nv天堂香蕉在线观看 | 台湾无码一区二区 | 丰满人妻精品国产99aⅴ | 欧美丰满熟妇xxxx | 少妇被黑人到高潮喷出白浆 | 欧美 亚洲 国产 另类 | 中文毛片无遮挡高清免费 | 亚洲国产av精品一区二区蜜芽 | 国产精品多人p群无码 | 一本久久a久久精品亚洲 | 色噜噜亚洲男人的天堂 | 亚洲一区二区三区四区 | 色偷偷人人澡人人爽人人模 | 国产97人人超碰caoprom | 88国产精品欧美一区二区三区 | 爆乳一区二区三区无码 | 亚洲第一网站男人都懂 | 亚洲成色在线综合网站 | 久久久av男人的天堂 | 亚洲欧洲日本综合aⅴ在线 | 成人影院yy111111在线观看 | 精品乱码久久久久久久 | 成人一在线视频日韩国产 | 女人被男人躁得好爽免费视频 | 少妇性俱乐部纵欲狂欢电影 | yw尤物av无码国产在线观看 | 狂野欧美性猛交免费视频 | 国产福利视频一区二区 | 99精品无人区乱码1区2区3区 | 亚洲va欧美va天堂v国产综合 | 国内精品人妻无码久久久影院蜜桃 | 亚洲va欧美va天堂v国产综合 | 久久久久亚洲精品中文字幕 | 波多野结衣 黑人 | 久久天天躁狠狠躁夜夜免费观看 | 免费观看又污又黄的网站 | 国产成人无码av在线影院 | 日本va欧美va欧美va精品 | 国产在线精品一区二区三区直播 | 亚洲精品中文字幕久久久久 | 亚洲一区二区三区含羞草 | 丰满妇女强制高潮18xxxx | 天堂а√在线中文在线 | 少妇久久久久久人妻无码 | 51国偷自产一区二区三区 | 成年美女黄网站色大免费全看 | 精品无码国产一区二区三区av | 亚洲综合无码一区二区三区 | 人人妻人人澡人人爽人人精品 | a片免费视频在线观看 | 精品国产一区二区三区四区 | 2020久久香蕉国产线看观看 | 精品一二三区久久aaa片 | 国产精品久免费的黄网站 | 日韩精品无码免费一区二区三区 | 亚洲s码欧洲m码国产av | 国产乱人伦偷精品视频 | 图片区 小说区 区 亚洲五月 | 一本一道久久综合久久 | 成人免费无码大片a毛片 | 丰满妇女强制高潮18xxxx | 国产精品亚洲专区无码不卡 | 色婷婷香蕉在线一区二区 | 亚洲色欲色欲欲www在线 | 97精品人妻一区二区三区香蕉 | 国产成人无码区免费内射一片色欲 | 国产亚洲人成在线播放 | 人人妻人人藻人人爽欧美一区 | av在线亚洲欧洲日产一区二区 | 天海翼激烈高潮到腰振不止 | 亚洲欧美色中文字幕在线 | 真人与拘做受免费视频一 | 55夜色66夜色国产精品视频 | 香港三级日本三级妇三级 | 欧美高清在线精品一区 | 中文字幕乱码人妻无码久久 | 大肉大捧一进一出视频出来呀 | 国产艳妇av在线观看果冻传媒 | 无码午夜成人1000部免费视频 | 曰本女人与公拘交酡免费视频 | 在线 国产 欧美 亚洲 天堂 | 人人妻人人澡人人爽欧美精品 | 精品人人妻人人澡人人爽人人 | 人人妻人人澡人人爽欧美一区 | 国产成人无码一二三区视频 | 国产网红无码精品视频 | 婷婷丁香五月天综合东京热 | 欧美人与物videos另类 | 国产三级久久久精品麻豆三级 | 国产舌乚八伦偷品w中 | 久久精品国产99久久6动漫 | 免费播放一区二区三区 | 国产特级毛片aaaaaa高潮流水 | 丰满人妻被黑人猛烈进入 | 大色综合色综合网站 | 搡女人真爽免费视频大全 | 内射老妇bbwx0c0ck | 老熟妇乱子伦牲交视频 | 国产精品久免费的黄网站 | 精品人妻人人做人人爽 | 在线а√天堂中文官网 | 亚洲男人av香蕉爽爽爽爽 | 熟妇女人妻丰满少妇中文字幕 | 日本熟妇乱子伦xxxx | 日日橹狠狠爱欧美视频 | 欧美午夜特黄aaaaaa片 | 人人妻人人澡人人爽欧美精品 | 无码精品国产va在线观看dvd | 国产成人精品一区二区在线小狼 | 99视频精品全部免费免费观看 | 亚洲一区二区三区无码久久 | 国产成人综合色在线观看网站 | 日本饥渴人妻欲求不满 | 久久国产劲爆∧v内射 | 国产亚洲精品久久久久久久 | 国产成人一区二区三区别 | 少妇人妻大乳在线视频 | 人人澡人人透人人爽 | 国产成人无码专区 | 国产sm调教视频在线观看 | 亚洲の无码国产の无码影院 | 亚洲中文字幕va福利 | 少妇激情av一区二区 | 性欧美videos高清精品 | 纯爱无遮挡h肉动漫在线播放 | 欧美日韩一区二区免费视频 | 国产手机在线αⅴ片无码观看 | 少妇无码一区二区二三区 | 伊在人天堂亚洲香蕉精品区 | 亚洲精品久久久久久一区二区 | 国产成人无码av片在线观看不卡 | 老熟女重囗味hdxx69 | 人妻无码αv中文字幕久久琪琪布 | 男女猛烈xx00免费视频试看 | 3d动漫精品啪啪一区二区中 | 黑人大群体交免费视频 | 久久午夜无码鲁丝片午夜精品 | 爱做久久久久久 | 国产精品毛片一区二区 | 国产69精品久久久久app下载 | 国产亚洲精品久久久久久久 | 内射爽无广熟女亚洲 | 自拍偷自拍亚洲精品10p | 久久综合九色综合欧美狠狠 | 欧美激情内射喷水高潮 | 亚洲精品国产精品乱码不卡 | 国产精品a成v人在线播放 | 国产成人精品视频ⅴa片软件竹菊 | 久久综合九色综合欧美狠狠 | 精品国产国产综合精品 | 动漫av网站免费观看 | 欧美日本日韩 | 2020最新国产自产精品 | 国产精品亚洲lv粉色 | 无码国内精品人妻少妇 | 国产极品美女高潮无套在线观看 | 亚洲欧洲无卡二区视頻 | 中文无码精品a∨在线观看不卡 | 爱做久久久久久 | 精品人妻人人做人人爽 | 天堂а√在线中文在线 | 四十如虎的丰满熟妇啪啪 | 夜夜夜高潮夜夜爽夜夜爰爰 | 国产色精品久久人妻 | 波多野42部无码喷潮在线 | 3d动漫精品啪啪一区二区中 | 亚洲中文字幕无码中文字在线 | 久久亚洲精品中文字幕无男同 | 大肉大捧一进一出视频出来呀 | 亚洲色成人中文字幕网站 | 2020久久香蕉国产线看观看 | 丝袜 中出 制服 人妻 美腿 | 少妇性l交大片 | 国产av无码专区亚洲awww | 白嫩日本少妇做爰 | 成人欧美一区二区三区黑人 | 午夜无码区在线观看 | 丰满少妇女裸体bbw | 麻豆国产人妻欲求不满 | 国产亚洲tv在线观看 | 中文精品久久久久人妻不卡 | 亚洲精品国产a久久久久久 | 又大又黄又粗又爽的免费视频 | 国产综合久久久久鬼色 | 日日天干夜夜狠狠爱 | 无码人妻丰满熟妇区毛片18 | 中文字幕无码人妻少妇免费 | 日日噜噜噜噜夜夜爽亚洲精品 | 波多野结衣aⅴ在线 | 少妇高潮一区二区三区99 | 综合人妻久久一区二区精品 | 国产精品自产拍在线观看 | 曰韩少妇内射免费播放 | 青青青爽视频在线观看 | 亚洲区欧美区综合区自拍区 | 人人澡人人透人人爽 | 国产亚洲精品久久久闺蜜 | 日日鲁鲁鲁夜夜爽爽狠狠 | 狠狠色欧美亚洲狠狠色www | 永久免费观看美女裸体的网站 | 久久亚洲中文字幕精品一区 | 亚洲综合伊人久久大杳蕉 | 成在人线av无码免观看麻豆 | 亚洲呦女专区 | 高清国产亚洲精品自在久久 | 人妻aⅴ无码一区二区三区 | 日日天日日夜日日摸 | 无人区乱码一区二区三区 | 樱花草在线播放免费中文 | 国产精品第一区揄拍无码 | 亚洲欧美日韩国产精品一区二区 | 狠狠亚洲超碰狼人久久 | 国产va免费精品观看 | 99视频精品全部免费免费观看 | 成人一在线视频日韩国产 | 久久久国产精品无码免费专区 | 一本加勒比波多野结衣 | 日韩在线不卡免费视频一区 | 夜夜躁日日躁狠狠久久av | 桃花色综合影院 | 久久这里只有精品视频9 | 国产av人人夜夜澡人人爽麻豆 | 久久午夜无码鲁丝片秋霞 | 沈阳熟女露脸对白视频 | 亚洲中文字幕无码中字 | 国产超碰人人爽人人做人人添 | 亚洲娇小与黑人巨大交 | √天堂资源地址中文在线 | 国产又爽又黄又刺激的视频 | 国语精品一区二区三区 | 亚洲欧美精品伊人久久 | 精品国产乱码久久久久乱码 | 亚洲精品成人福利网站 | 欧美日韩综合一区二区三区 | 日欧一片内射va在线影院 | 亚洲国产精品一区二区第一页 | 红桃av一区二区三区在线无码av | 精品无码成人片一区二区98 | 无码国产激情在线观看 | 日日噜噜噜噜夜夜爽亚洲精品 | 久久精品国产精品国产精品污 | 无码国产激情在线观看 | 婷婷六月久久综合丁香 | 日韩精品无码一区二区中文字幕 | 免费无码肉片在线观看 | 成年女人永久免费看片 | 欧美日韩在线亚洲综合国产人 | 国产精品va在线观看无码 | 久久zyz资源站无码中文动漫 | 牲欲强的熟妇农村老妇女 | 日韩av无码一区二区三区不卡 | 奇米影视888欧美在线观看 | 性欧美熟妇videofreesex | 亚洲va中文字幕无码久久不卡 | 色婷婷综合中文久久一本 | 久久综合九色综合欧美狠狠 | 麻豆国产人妻欲求不满谁演的 | 老太婆性杂交欧美肥老太 | 欧美国产日韩亚洲中文 | 国产9 9在线 | 中文 | 亚洲成色在线综合网站 | aa片在线观看视频在线播放 | 亚洲一区二区三区 | 久久综合九色综合97网 | 国产精品美女久久久久av爽李琼 | 一本久道久久综合狠狠爱 | 亚洲国产日韩a在线播放 | 欧美变态另类xxxx | 青青青手机频在线观看 | 水蜜桃色314在线观看 | 超碰97人人做人人爱少妇 | 九九热爱视频精品 | 国产精品免费大片 | 精品久久久久久人妻无码中文字幕 | 天堂а√在线地址中文在线 | 亚洲乱码中文字幕在线 | 国模大胆一区二区三区 | 熟女少妇在线视频播放 | 高中生自慰www网站 | 又大又黄又粗又爽的免费视频 | 久久久国产精品无码免费专区 | 人人妻人人澡人人爽人人精品 | 伊人久久大香线焦av综合影院 | 图片区 小说区 区 亚洲五月 | 中文字幕乱码人妻无码久久 | 中国女人内谢69xxxx | 国产suv精品一区二区五 | 亚洲中文字幕va福利 | 性生交片免费无码看人 | 国产午夜精品一区二区三区嫩草 | 天天摸天天透天天添 | 国产超级va在线观看视频 | 少妇被黑人到高潮喷出白浆 | 青青草原综合久久大伊人精品 | 色五月五月丁香亚洲综合网 | 国内少妇偷人精品视频 | 国产精品人人爽人人做我的可爱 | 岛国片人妻三上悠亚 | 欧美国产日韩久久mv | 欧洲vodafone精品性 | 国内老熟妇对白xxxxhd | 久久国产精品偷任你爽任你 | 久久精品99久久香蕉国产色戒 | av在线亚洲欧洲日产一区二区 | 强奷人妻日本中文字幕 | 成人试看120秒体验区 | 精品国产麻豆免费人成网站 | 中文字幕无码免费久久99 | 51国偷自产一区二区三区 | 丁香花在线影院观看在线播放 | 亚洲一区二区三区四区 | 国产在线无码精品电影网 | 麻豆av传媒蜜桃天美传媒 | 少妇人妻偷人精品无码视频 | 无套内射视频囯产 | 亚洲精品久久久久久一区二区 | 在线亚洲高清揄拍自拍一品区 | 狂野欧美激情性xxxx | 久久久久免费精品国产 | 婷婷色婷婷开心五月四房播播 | 极品尤物被啪到呻吟喷水 | 中文字幕无码乱人伦 | 大地资源网第二页免费观看 | 色综合久久中文娱乐网 | 久久99精品久久久久婷婷 | 日韩精品无码一区二区中文字幕 | 老熟妇仑乱视频一区二区 | 久久精品丝袜高跟鞋 | 国产色在线 | 国产 | 国产av无码专区亚洲awww | 国产亚洲欧美在线专区 | 一本精品99久久精品77 | 人妻体内射精一区二区三四 | 久久精品一区二区三区四区 | ass日本丰满熟妇pics | 无码毛片视频一区二区本码 | 内射爽无广熟女亚洲 | 精品国产乱码久久久久乱码 | 亚洲精品一区二区三区在线观看 | 粉嫩少妇内射浓精videos | 久久99精品久久久久婷婷 | 国产综合在线观看 | 亚洲国产精品久久人人爱 | 99久久精品国产一区二区蜜芽 | 久青草影院在线观看国产 | 在线成人www免费观看视频 | 亚洲精品一区二区三区大桥未久 | 国产美女极度色诱视频www | 亚洲国产欧美日韩精品一区二区三区 | 中文字幕乱码中文乱码51精品 | 伊人久久大香线蕉午夜 | 日本精品少妇一区二区三区 | 露脸叫床粗话东北少妇 | 中文无码成人免费视频在线观看 | 日日鲁鲁鲁夜夜爽爽狠狠 | 中文字幕乱妇无码av在线 | 天干天干啦夜天干天2017 | 国产精品嫩草久久久久 | 日韩人妻无码一区二区三区久久99 | 欧美老妇交乱视频在线观看 | 精品久久综合1区2区3区激情 | 亚洲伊人久久精品影院 | 国产农村乱对白刺激视频 | 国产手机在线αⅴ片无码观看 | 少妇人妻av毛片在线看 | 国产亚洲欧美日韩亚洲中文色 | 久久99精品国产.久久久久 | 熟女体下毛毛黑森林 | 国产在线aaa片一区二区99 | 成年女人永久免费看片 | 欧美xxxx黑人又粗又长 | 99精品视频在线观看免费 | 亚洲欧美精品伊人久久 | 性色欲网站人妻丰满中文久久不卡 | 麻豆果冻传媒2021精品传媒一区下载 | 少妇人妻偷人精品无码视频 | 成 人 网 站国产免费观看 | 日韩精品乱码av一区二区 | 日韩av无码一区二区三区不卡 | 免费播放一区二区三区 | 少妇厨房愉情理9仑片视频 | 国产97色在线 | 免 | 日本va欧美va欧美va精品 | 久久久无码中文字幕久... | 欧美野外疯狂做受xxxx高潮 | 国产精品无码一区二区桃花视频 | 国产莉萝无码av在线播放 | 久久久中文久久久无码 | 最新国产麻豆aⅴ精品无码 | 性色欲情网站iwww九文堂 | 在线观看免费人成视频 | 日本va欧美va欧美va精品 | 国内揄拍国内精品少妇国语 | 欧美丰满少妇xxxx性 | 久久熟妇人妻午夜寂寞影院 | 欧洲精品码一区二区三区免费看 | 国产极品美女高潮无套在线观看 | 捆绑白丝粉色jk震动捧喷白浆 | 少妇厨房愉情理9仑片视频 | 亚洲熟妇自偷自拍另类 | 无码午夜成人1000部免费视频 | 国产亚洲精品精品国产亚洲综合 | 国产精品理论片在线观看 | 扒开双腿疯狂进出爽爽爽视频 | 国产精品理论片在线观看 | 亚洲国产精品久久久久久 | av香港经典三级级 在线 | 午夜免费福利小电影 | 日产精品99久久久久久 | 性生交大片免费看l | 无码人妻少妇伦在线电影 | 中文字幕 亚洲精品 第1页 | 小sao货水好多真紧h无码视频 | 国产无av码在线观看 | 宝宝好涨水快流出来免费视频 | 综合激情五月综合激情五月激情1 | 青春草在线视频免费观看 | 亚洲精品综合一区二区三区在线 | 无码精品人妻一区二区三区av | 国产av一区二区三区最新精品 | 欧美三级a做爰在线观看 | 熟妇人妻激情偷爽文 | 欧美日韩人成综合在线播放 | 国产精品高潮呻吟av久久4虎 | 亚洲熟妇色xxxxx欧美老妇 | 熟妇人妻无码xxx视频 | 成年美女黄网站色大免费全看 | 国产农村妇女高潮大叫 | 欧美精品一区二区精品久久 | 十八禁真人啪啪免费网站 | 无码人妻av免费一区二区三区 | 少妇无码av无码专区在线观看 | 国产超级va在线观看视频 | 国产精品高潮呻吟av久久 | 伊人久久大香线蕉午夜 | 大胆欧美熟妇xx | 丰满少妇高潮惨叫视频 | 成人一在线视频日韩国产 | 亚洲狠狠婷婷综合久久 | 中文字幕无码乱人伦 | 日日躁夜夜躁狠狠躁 | 九月婷婷人人澡人人添人人爽 | 久久久久久av无码免费看大片 | 国产美女极度色诱视频www | 亚洲 另类 在线 欧美 制服 | 乌克兰少妇性做爰 | v一区无码内射国产 | 亚洲自偷自拍另类第1页 | 51国偷自产一区二区三区 | 成人免费视频一区二区 | 国产成人无码一二三区视频 | 丰满岳乱妇在线观看中字无码 | 亚洲精品综合五月久久小说 | 天堂亚洲2017在线观看 | 午夜无码人妻av大片色欲 | 少妇无码av无码专区在线观看 | av无码电影一区二区三区 | 少妇性荡欲午夜性开放视频剧场 | 综合激情五月综合激情五月激情1 | 思思久久99热只有频精品66 | 内射爽无广熟女亚洲 | 少妇被黑人到高潮喷出白浆 | 最新国产麻豆aⅴ精品无码 | 中文字幕乱码中文乱码51精品 | 少妇性荡欲午夜性开放视频剧场 | 久久久婷婷五月亚洲97号色 | 精品无码一区二区三区的天堂 | 午夜福利一区二区三区在线观看 | 亚洲日韩av一区二区三区四区 | 国产69精品久久久久app下载 | 丰满少妇人妻久久久久久 | 扒开双腿疯狂进出爽爽爽视频 | 狠狠亚洲超碰狼人久久 | 曰本女人与公拘交酡免费视频 | 全黄性性激高免费视频 | 无套内谢老熟女 | 欧美变态另类xxxx | 日本大香伊一区二区三区 | 亚洲成av人片在线观看无码不卡 | 男女下面进入的视频免费午夜 | 国产乱人无码伦av在线a | 东京热无码av男人的天堂 | 亚洲精品无码国产 | 国产精华av午夜在线观看 | 欧美午夜特黄aaaaaa片 | 亚洲国产精华液网站w | 无码一区二区三区在线观看 | 免费看男女做好爽好硬视频 | 国产一区二区三区日韩精品 | 老熟女重囗味hdxx69 | 无人区乱码一区二区三区 | 俺去俺来也在线www色官网 | 久久综合九色综合欧美狠狠 | 曰本女人与公拘交酡免费视频 | 国产精品永久免费视频 | 欧美野外疯狂做受xxxx高潮 | 国产人成高清在线视频99最全资源 | 狠狠色噜噜狠狠狠7777奇米 | 国产成人无码a区在线观看视频app | 久久精品无码一区二区三区 | 国产片av国语在线观看 | 76少妇精品导航 | 内射巨臀欧美在线视频 | 97久久精品无码一区二区 | 亚洲中文字幕无码中文字在线 | 人妻少妇精品久久 | 宝宝好涨水快流出来免费视频 | 一个人看的www免费视频在线观看 | 亚洲欧美色中文字幕在线 | 国产内射老熟女aaaa | 免费观看的无遮挡av | 国产亚洲视频中文字幕97精品 | 久久人人爽人人人人片 | 暴力强奷在线播放无码 | 色妞www精品免费视频 | 亚洲人成影院在线无码按摩店 | 国产无套内射久久久国产 | 色一情一乱一伦 | 亚洲色欲色欲欲www在线 | 国产亚洲人成a在线v网站 | 国产无遮挡又黄又爽又色 | 亚洲 欧美 激情 小说 另类 | 精品无码一区二区三区爱欲 | 亚洲综合伊人久久大杳蕉 | 久久五月精品中文字幕 | 精品久久久无码中文字幕 | 国产精品鲁鲁鲁 | 久久天天躁夜夜躁狠狠 | 久久亚洲a片com人成 | 高中生自慰www网站 | 精品亚洲成av人在线观看 | 免费观看又污又黄的网站 | av在线亚洲欧洲日产一区二区 | 亚洲第一无码av无码专区 | 欧美成人高清在线播放 | 青春草在线视频免费观看 | 国产亚洲精品久久久久久久久动漫 | 国产精品香蕉在线观看 | 亚洲男人av天堂午夜在 | 精品久久久无码中文字幕 | 色 综合 欧美 亚洲 国产 | 午夜福利电影 | 四虎4hu永久免费 | 曰韩无码二三区中文字幕 | 国产乱子伦视频在线播放 | 精品成人av一区二区三区 | 日韩少妇白浆无码系列 | 真人与拘做受免费视频 | 国产精品亚洲综合色区韩国 | 少妇久久久久久人妻无码 | 亚洲国精产品一二二线 | 狠狠色丁香久久婷婷综合五月 | 又粗又大又硬毛片免费看 | 98国产精品综合一区二区三区 | 亚洲 a v无 码免 费 成 人 a v | 国产人妻久久精品二区三区老狼 | 欧美激情内射喷水高潮 | 一个人看的视频www在线 | 无码人妻丰满熟妇区毛片18 | 色婷婷香蕉在线一区二区 | 99久久精品国产一区二区蜜芽 | 丝袜人妻一区二区三区 | 特大黑人娇小亚洲女 | 在线观看免费人成视频 | 亚洲a无码综合a国产av中文 | 精品一二三区久久aaa片 | 亚洲一区二区三区在线观看网站 | 少妇人妻偷人精品无码视频 | 国产特级毛片aaaaaaa高清 | 小sao货水好多真紧h无码视频 | 国产精品久久久午夜夜伦鲁鲁 | 中文字幕无码热在线视频 | 国产成人无码一二三区视频 | 人妻夜夜爽天天爽三区 | 日本欧美一区二区三区乱码 | √8天堂资源地址中文在线 | 亚洲男人av天堂午夜在 | 久久熟妇人妻午夜寂寞影院 | 任你躁国产自任一区二区三区 | 久久综合色之久久综合 | 日韩人妻无码中文字幕视频 | 国产深夜福利视频在线 | 久久伊人色av天堂九九小黄鸭 | 久久精品国产日本波多野结衣 | 亚洲欧美精品aaaaaa片 | 一本色道久久综合狠狠躁 | 在线观看免费人成视频 | 丰满人妻一区二区三区免费视频 | 久久亚洲a片com人成 | av无码不卡在线观看免费 | 2019nv天堂香蕉在线观看 | 欧美兽交xxxx×视频 | 精品无码一区二区三区的天堂 | 亚洲综合无码一区二区三区 | 日本免费一区二区三区最新 | 国产精品亚洲lv粉色 | 精品欧洲av无码一区二区三区 | 亚洲天堂2017无码中文 | 久久熟妇人妻午夜寂寞影院 | 国产xxx69麻豆国语对白 | 欧美自拍另类欧美综合图片区 | 久久国产精品偷任你爽任你 | 国产亚洲日韩欧美另类第八页 | 久久久久国色av免费观看性色 | 久久午夜无码鲁丝片午夜精品 | 日本一卡二卡不卡视频查询 | 色欲综合久久中文字幕网 | 国产真人无遮挡作爱免费视频 | 中文字幕无线码 | 午夜福利一区二区三区在线观看 | 人人澡人人透人人爽 | 久久久久99精品国产片 | 国产精华av午夜在线观看 | 午夜无码区在线观看 | 国产精华av午夜在线观看 | 久久zyz资源站无码中文动漫 | 内射欧美老妇wbb | 丰满护士巨好爽好大乳 | 亚洲自偷自拍另类第1页 | 人人澡人人透人人爽 | 国产免费观看黄av片 | 骚片av蜜桃精品一区 | 国産精品久久久久久久 | 免费中文字幕日韩欧美 | 欧美精品在线观看 | 国产香蕉尹人综合在线观看 | 波多野结衣av一区二区全免费观看 | 亚洲啪av永久无码精品放毛片 | 亚洲精品国偷拍自产在线麻豆 | 无套内射视频囯产 | 欧美日韩亚洲国产精品 | 综合人妻久久一区二区精品 | 亚洲啪av永久无码精品放毛片 | 日韩av无码中文无码电影 | 亚洲国产精品久久久天堂 | 国产色视频一区二区三区 | 国产亚洲精品久久久久久大师 | 人人妻人人澡人人爽欧美一区九九 | 国产午夜亚洲精品不卡 | 人妻aⅴ无码一区二区三区 | 免费视频欧美无人区码 | 亚洲欧洲日本综合aⅴ在线 | 亚洲国产成人a精品不卡在线 | 内射白嫩少妇超碰 | 欧洲美熟女乱又伦 | 日本护士毛茸茸高潮 | 青春草在线视频免费观看 | 性做久久久久久久免费看 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 精品一二三区久久aaa片 | 国产一区二区不卡老阿姨 | 少妇性l交大片欧洲热妇乱xxx | 伊人久久大香线蕉亚洲 | 人妻少妇被猛烈进入中文字幕 | 粗大的内捧猛烈进出视频 | 色妞www精品免费视频 | 久久精品国产大片免费观看 | 在线观看国产午夜福利片 | 无码一区二区三区在线观看 | 日日噜噜噜噜夜夜爽亚洲精品 | 无码国模国产在线观看 | 野狼第一精品社区 | 欧美xxxx黑人又粗又长 | aⅴ亚洲 日韩 色 图网站 播放 | 亚洲熟妇色xxxxx欧美老妇y | 在线天堂新版最新版在线8 | 丰满少妇熟乱xxxxx视频 | 久久久成人毛片无码 | 久久久久免费精品国产 | 国模大胆一区二区三区 | 奇米影视7777久久精品人人爽 | 国产婷婷色一区二区三区在线 | 特级做a爰片毛片免费69 | 综合激情五月综合激情五月激情1 | 亚洲 激情 小说 另类 欧美 | 欧美 丝袜 自拍 制服 另类 | 无码av岛国片在线播放 | 亚洲精品午夜无码电影网 | 国产区女主播在线观看 | 国产真人无遮挡作爱免费视频 | 国产麻豆精品一区二区三区v视界 | 国产精品内射视频免费 | 午夜福利电影 | 激情内射亚州一区二区三区爱妻 | 国产猛烈高潮尖叫视频免费 | 熟女俱乐部五十路六十路av | 国产特级毛片aaaaaa高潮流水 | 日韩少妇内射免费播放 | 亚洲综合色区中文字幕 | 久久久久久久人妻无码中文字幕爆 | 波多野结衣高清一区二区三区 | 国产99久久精品一区二区 | 在线天堂新版最新版在线8 | 亚洲成色在线综合网站 | 亚洲男女内射在线播放 | 成人性做爰aaa片免费看不忠 | 爱做久久久久久 | 成人一在线视频日韩国产 | 无码国产激情在线观看 | 国产熟妇高潮叫床视频播放 | 无码人妻精品一区二区三区不卡 | 亚洲日本va午夜在线电影 | 少妇性俱乐部纵欲狂欢电影 | 1000部夫妻午夜免费 | 亚洲 另类 在线 欧美 制服 | 婷婷色婷婷开心五月四房播播 | 国产人妖乱国产精品人妖 | 东北女人啪啪对白 | 亚洲小说春色综合另类 | 国产免费无码一区二区视频 | 国产午夜精品一区二区三区嫩草 | 欧美高清在线精品一区 | 国产精品高潮呻吟av久久4虎 | 国产乱人偷精品人妻a片 | 久久99久久99精品中文字幕 | 小sao货水好多真紧h无码视频 | 亚洲男人av天堂午夜在 | 少妇高潮喷潮久久久影院 | 丰满少妇熟乱xxxxx视频 | 99国产精品白浆在线观看免费 | 国产免费观看黄av片 | 亚洲 a v无 码免 费 成 人 a v | 狂野欧美性猛xxxx乱大交 | 青春草在线视频免费观看 | 国产农村妇女高潮大叫 | 婷婷六月久久综合丁香 | 国产激情一区二区三区 | 国产9 9在线 | 中文 | 任你躁在线精品免费 | 77777熟女视频在线观看 а天堂中文在线官网 | 天堂а√在线地址中文在线 | 激情五月综合色婷婷一区二区 | 亚洲第一网站男人都懂 | 无人区乱码一区二区三区 | 性欧美videos高清精品 | 国产精品视频免费播放 | 日韩欧美群交p片內射中文 | 久久国产36精品色熟妇 | 国产精品人人妻人人爽 | 国产麻豆精品一区二区三区v视界 | 国产真人无遮挡作爱免费视频 | 国产精品久久精品三级 | 夜精品a片一区二区三区无码白浆 | 欧洲美熟女乱又伦 | 东京无码熟妇人妻av在线网址 | 亚洲欧美中文字幕5发布 | 18精品久久久无码午夜福利 | 蜜臀aⅴ国产精品久久久国产老师 | 扒开双腿吃奶呻吟做受视频 | 亚洲中文字幕久久无码 | 欧美亚洲日韩国产人成在线播放 | 亚洲精品一区二区三区四区五区 | 久久精品成人欧美大片 | 四虎影视成人永久免费观看视频 | 成人亚洲精品久久久久 | 97久久超碰中文字幕 | 欧美人与牲动交xxxx | 欧美成人家庭影院 | 中文精品久久久久人妻不卡 | 国产莉萝无码av在线播放 | 欧美性生交活xxxxxdddd | 欧美老熟妇乱xxxxx | 午夜福利不卡在线视频 | 国产综合色产在线精品 | 亚洲国产一区二区三区在线观看 | 青青青爽视频在线观看 | 丰满妇女强制高潮18xxxx | 欧美日韩色另类综合 | 国产亚洲欧美日韩亚洲中文色 | 荫蒂添的好舒服视频囗交 | 天堂а√在线中文在线 | 麻豆果冻传媒2021精品传媒一区下载 | 日日碰狠狠丁香久燥 | 老司机亚洲精品影院无码 | 日本精品人妻无码免费大全 | 色窝窝无码一区二区三区色欲 | 丰满少妇女裸体bbw | 亚洲精品久久久久久久久久久 | 欧美大屁股xxxxhd黑色 | 又粗又大又硬又长又爽 | 欧美国产日产一区二区 | 久久99精品国产麻豆 | 亚洲天堂2017无码 | 中文字幕av日韩精品一区二区 | 牲欲强的熟妇农村老妇女视频 | 无码午夜成人1000部免费视频 | 亚洲精品一区二区三区在线观看 | 水蜜桃色314在线观看 | 午夜精品久久久久久久久 | 无码一区二区三区在线观看 | 亚洲精品午夜国产va久久成人 | 久久亚洲精品成人无码 | 亚拍精品一区二区三区探花 | 国产亚洲欧美在线专区 | 免费网站看v片在线18禁无码 | 在线成人www免费观看视频 | 无码精品人妻一区二区三区av | 成年美女黄网站色大免费视频 | 久久国产劲爆∧v内射 | 伊人色综合久久天天小片 | 乱码av麻豆丝袜熟女系列 | 欧美 日韩 人妻 高清 中文 | 好屌草这里只有精品 | 亚洲精品美女久久久久久久 | 亚洲国产精品无码久久久久高潮 | 久久综合九色综合97网 | 一个人看的www免费视频在线观看 | 精品一区二区三区波多野结衣 | 中文字幕无码免费久久9一区9 | 曰本女人与公拘交酡免费视频 | 麻豆国产人妻欲求不满 | 亚洲精品综合一区二区三区在线 | 夜精品a片一区二区三区无码白浆 | 亚洲国产成人a精品不卡在线 | 久久久久人妻一区精品色欧美 | 欧美激情综合亚洲一二区 | 亚洲欧美中文字幕5发布 | 精品一二三区久久aaa片 | 国产亚洲精品久久久久久久 | 国产成人综合美国十次 | 日韩少妇白浆无码系列 | 午夜丰满少妇性开放视频 | 日韩精品无码一区二区中文字幕 | 无码人妻精品一区二区三区不卡 | 国产在线精品一区二区三区直播 | 青草视频在线播放 | 对白脏话肉麻粗话av | 女人被男人爽到呻吟的视频 | 日本成熟视频免费视频 | 红桃av一区二区三区在线无码av | 亚洲中文字幕无码中文字在线 | 真人与拘做受免费视频 | 狠狠cao日日穞夜夜穞av | 色爱情人网站 | 无码任你躁久久久久久久 | 伦伦影院午夜理论片 | 日本高清一区免费中文视频 | 日韩精品无码免费一区二区三区 | 国产色精品久久人妻 | 在线精品国产一区二区三区 | 97久久超碰中文字幕 | 国产成人一区二区三区在线观看 | 色 综合 欧美 亚洲 国产 | 国产精品.xx视频.xxtv | 亚洲欧美日韩综合久久久 | 精品久久久久久亚洲精品 | 日韩人妻少妇一区二区三区 | 国产精品久久久久久久影院 | 欧美性生交xxxxx久久久 | 九九综合va免费看 | 最新国产乱人伦偷精品免费网站 | 国产三级久久久精品麻豆三级 | 色综合久久88色综合天天 | 欧美老人巨大xxxx做受 | 国产精品久久久久久久影院 | 久久精品国产大片免费观看 | 亚洲乱亚洲乱妇50p | 无码人妻少妇伦在线电影 | 国产网红无码精品视频 | 日本饥渴人妻欲求不满 | 久久久久99精品国产片 | 国产人成高清在线视频99最全资源 | 人妻夜夜爽天天爽三区 | 三上悠亚人妻中文字幕在线 | 红桃av一区二区三区在线无码av | 无码国产色欲xxxxx视频 | 久久国产精品精品国产色婷婷 | 蜜桃av抽搐高潮一区二区 | 无码国模国产在线观看 | 亚洲精品综合一区二区三区在线 | 97夜夜澡人人爽人人喊中国片 | 给我免费的视频在线观看 | 亚洲国产精品美女久久久久 | 亚洲伊人久久精品影院 | 久久综合给合久久狠狠狠97色 | 国产亚洲精品久久久闺蜜 | 中文无码精品a∨在线观看不卡 | 在线成人www免费观看视频 | 欧美激情一区二区三区成人 | 国产性生大片免费观看性 | 老司机亚洲精品影院 | 日韩精品无码一区二区中文字幕 | av无码久久久久不卡免费网站 | 乱人伦中文视频在线观看 | 欧美国产日韩久久mv | 网友自拍区视频精品 | 国语自产偷拍精品视频偷 | 狠狠噜狠狠狠狠丁香五月 | 国产激情无码一区二区app | 久久国产劲爆∧v内射 | 大地资源中文第3页 | 欧美 日韩 亚洲 在线 | 又大又黄又粗又爽的免费视频 | 亚洲 另类 在线 欧美 制服 | 成 人 网 站国产免费观看 | 最近免费中文字幕中文高清百度 | 强奷人妻日本中文字幕 | 成人aaa片一区国产精品 | 三上悠亚人妻中文字幕在线 | 欧美 丝袜 自拍 制服 另类 | 久久精品中文闷骚内射 | 亚洲色成人中文字幕网站 | 亚洲第一无码av无码专区 | 鲁鲁鲁爽爽爽在线视频观看 | a片免费视频在线观看 | 国产莉萝无码av在线播放 | 国产猛烈高潮尖叫视频免费 | 国产免费久久精品国产传媒 | 国产精品理论片在线观看 | 国产免费观看黄av片 | 欧美精品一区二区精品久久 | 亚洲精品无码国产 | 欧美freesex黑人又粗又大 | 四虎影视成人永久免费观看视频 | 中文精品无码中文字幕无码专区 | 日韩亚洲欧美中文高清在线 | 乱人伦人妻中文字幕无码久久网 | 377p欧洲日本亚洲大胆 | 免费播放一区二区三区 | 亚洲 a v无 码免 费 成 人 a v | √天堂资源地址中文在线 | 国产色视频一区二区三区 | 正在播放老肥熟妇露脸 | 奇米影视7777久久精品人人爽 | 伦伦影院午夜理论片 | 亚洲一区二区三区 | 丰满少妇弄高潮了www | 国产亚洲精品久久久久久久久动漫 | 国产综合在线观看 | 亚洲一区二区三区在线观看网站 | 亚洲精品久久久久avwww潮水 | 国产香蕉97碰碰久久人人 | 国产精品嫩草久久久久 | 欧美亚洲国产一区二区三区 | 亚洲第一网站男人都懂 | 久久人人爽人人爽人人片av高清 | 久久精品国产99久久6动漫 | av无码久久久久不卡免费网站 | 欧美变态另类xxxx | 国产精品美女久久久网av | 日本精品少妇一区二区三区 | 少女韩国电视剧在线观看完整 | 欧美人与物videos另类 | 鲁鲁鲁爽爽爽在线视频观看 | 乌克兰少妇xxxx做受 | 最近中文2019字幕第二页 | 中文字幕无码日韩欧毛 | 国产精品久久久久久亚洲影视内衣 |