请问 这个 type T_ic_init = function() 是什么用法

时间:2021-03-01 02:41:32
代码如下:
// unit Drive_MHUnit;    

type  
  T_ic_init = function(port: smallint; baud: longint): longint; stdcall; 

// unit CardDrive_4442;
   ic_init: T_ic_init;

// unit CardDrive_4442;
   @ic_init := GetProcAddress(Th_DLL, PChar('ic_init'));

请问这个
type  
  T_ic_init = function(port: smallint; baud: longint): longint; stdcall; 

是什么用法

5 个解决方案

#1


你可以把这个当成一个自定义的函数类型

#2


实际上就是函数指针,Delphi中称之为“Procedural types”。

#3


引用 2 楼  的回复:
实际上就是函数指针,Delphi中称之为“Procedural types”。


还有更详细的解释吗

#4


引用 3 楼  的回复:
引用 2 楼 的回复:
实际上就是函数指针,Delphi中称之为“Procedural types”。


还有更详细的解释吗


Delphi 2007帮助(Procedural Types)
RAD Studio (Common)   

Procedural Types
About Procedural Types | Procedural Types in Statements and Expressions | See Also
Collapse AllProcedural types allow you to treat procedures and functions as values that can be assigned to variables or passed to other procedures and functions.

About Procedural Types
Procedural types allow you to treat procedures and functions as values that can be assigned to variables or passed to other procedures and functions. For example, suppose you define a function called Calc that takes two integer parameters and returns an integer: 

function Calc(X,Y: Integer): Integer;
You can assign the Calc function to the variable F: 

var F: function(X,Y: Integer): Integer;
F := Calc;
If you take any procedure or function heading and remove the identifier after the word procedure or function, what's left is the name of a procedural type. You can use such type names directly in variable declarations (as in the previous example) or to declare new types: 

type
  TIntegerFunction = function: Integer;
  TProcedure = procedure;
  TStrProc = procedure(const S: string);
  TMathFunc = function(X: Double): Double;
var
  F: TIntegerFunction;   { F is a parameterless function that returns an integer }
  Proc: TProcedure;      { Proc is a parameterless procedure }
  SP: TStrProc;          { SP is a procedure that takes a string parameter }
  M: TMathFunc;          { M is a function that takes a Double (real) parameter and returns a Double }
 
  procedure FuncProc(P: TIntegerFunction);  { FuncProc is a procedure whose only parameter is a parameterless integer-valued function }
On Win32, the variables shown in the previous example are all procedure pointers - that is, pointers to the address of a procedure or function. On the .NET platform, procedural types are implemented as delegates. If you want to reference a method of an instance object (see Classes and objects), you need to add the words of object to the procedural type name. For example 

type
  TMethod      = procedure of object;
  TNotifyEvent = procedure(Sender: TObject) of object;
These types represent method pointers. A method pointer is really a pair of pointers; the first stores the address of a method, and the second stores a reference to the object the method belongs to. Given the declarations 

type
  TNotifyEvent = procedure(Sender: TObject) of object;
  TMainForm = class(TForm)
    procedure ButtonClick(Sender: TObject);
     ...
  end;
var
  MainForm: TMainForm;
  OnClick: TNotifyEvent
we could make the following assignment. 

OnClick := MainForm.ButtonClick;
Two procedural types are compatible if they have 

the same calling convention, 
the same return value (or no return value), and 
the same number of parameters, with identically typed parameters in corresponding positions. (Parameter names do not matter.) 
On Win32, procedure pointer types are always incompatible with method pointer types, but this is not true on the .NET platform. The value nil can be assigned to any procedural type. 

Nested procedures and functions (routines declared within other routines) cannot be used as procedural values, nor can predefined procedures and functions. If you want to use a predefined routine like Length as a procedural value, write a wrapper for it: 

function FLength(S: string): Integer;
          begin
            Result := Length(S);
          end;
Procedural Types in Statements and Expressions
When a procedural variable is on the left side of an assignment statement, the compiler expects a procedural value on the right. The assignment makes the variable on the left a pointer to the function or procedure indicated on the right. In other contexts, however, using a procedural variable results in a call to the referenced procedure or function. You can even use a procedural variable to pass parameters: 

var
  F: function(X: Integer): Integer;
  I: Integer;
  function SomeFunction(X: Integer): Integer;
    ...
  F := SomeFunction;    // assign SomeFunction to F
  I := F(4);            // call function; assign result to I
In assignment statements, the type of the variable on the left determines the interpretation of procedure or method pointers on the right. For example, 

var
  F, G: function: Integer;
  I: Integer;
  function SomeFunction: Integer;
    ...
  F := SomeFunction;      // assign SomeFunction to F
  G := F;                 // copy F to G
  I := G;                 // call function; assign result to I
The first statement assigns a procedural value to F. The second statement copies that value to another variable. The third statement makes a call to the referenced function and assigns the result to I. Because I is an integer variable, not a procedural one, the last assignment actually calls the function (which returns an integer). 

In some situations it is less clear how a procedural variable should be interpreted. Consider the statement 

if F = MyFunction then ...;
In this case, the occurrence of F results in a function call; the compiler calls the function pointed to by F, then calls the function MyFunction, then compares the results. The rule is that whenever a procedural variable occurs within an expression, it represents a call to the referenced procedure or function. In a case where F references a procedure (which doesn't return a value), or where F references a function that requires parameters, the previous statement causes a compilation error. To compare the procedural value of F with MyFunction, use 

if @F = @MyFunction then ...;
@F converts F into an untyped pointer variable that contains an address, and @MyFunction returns the address of MyFunction. 

To get the memory address of a procedural variable (rather than the address stored in it), use @@. For example, @@F returns the address of F. 

The @ operator can also be used to assign an untyped pointer value to a procedural variable. For example, 

var StrComp: function(Str1, Str2: PChar): Integer;
   ...
@StrComp := GetProcAddress(KernelHandle, 'lstrcmpi');
calls the GetProcAddress function and points StrComp to the result. 

Any procedural variable can hold the value nil, which means that it points to nothing. But attempting to call a nil-valued procedural variable is an error. To test whether a procedural variable is assigned, use the standard function Assigned: 

if Assigned(OnClick) then OnClick(X);
See Also
Data Types 

Simple Types 

String Types 

Structured Types 

Pointers and Pointer Types 

Variant Types 

Type Compatibility and Identity 

Declaring Types 

Variables 

Declared Constants

Copyright(C) 2008 CodeGear(TM). All Rights Reserved. 
What do you think about this topic? Send feedback!  

#5


详细的就是, 你可以指定这么一个类型的变量, 比如testfunc: T_ic_init
这个时候只要设置好testfunc的值, 就可以按照你定义的那样去调用, 比如
testfunc(1,2);

#1


你可以把这个当成一个自定义的函数类型

#2


实际上就是函数指针,Delphi中称之为“Procedural types”。

#3


引用 2 楼  的回复:
实际上就是函数指针,Delphi中称之为“Procedural types”。


还有更详细的解释吗

#4


引用 3 楼  的回复:
引用 2 楼 的回复:
实际上就是函数指针,Delphi中称之为“Procedural types”。


还有更详细的解释吗


Delphi 2007帮助(Procedural Types)
RAD Studio (Common)   

Procedural Types
About Procedural Types | Procedural Types in Statements and Expressions | See Also
Collapse AllProcedural types allow you to treat procedures and functions as values that can be assigned to variables or passed to other procedures and functions.

About Procedural Types
Procedural types allow you to treat procedures and functions as values that can be assigned to variables or passed to other procedures and functions. For example, suppose you define a function called Calc that takes two integer parameters and returns an integer: 

function Calc(X,Y: Integer): Integer;
You can assign the Calc function to the variable F: 

var F: function(X,Y: Integer): Integer;
F := Calc;
If you take any procedure or function heading and remove the identifier after the word procedure or function, what's left is the name of a procedural type. You can use such type names directly in variable declarations (as in the previous example) or to declare new types: 

type
  TIntegerFunction = function: Integer;
  TProcedure = procedure;
  TStrProc = procedure(const S: string);
  TMathFunc = function(X: Double): Double;
var
  F: TIntegerFunction;   { F is a parameterless function that returns an integer }
  Proc: TProcedure;      { Proc is a parameterless procedure }
  SP: TStrProc;          { SP is a procedure that takes a string parameter }
  M: TMathFunc;          { M is a function that takes a Double (real) parameter and returns a Double }
 
  procedure FuncProc(P: TIntegerFunction);  { FuncProc is a procedure whose only parameter is a parameterless integer-valued function }
On Win32, the variables shown in the previous example are all procedure pointers - that is, pointers to the address of a procedure or function. On the .NET platform, procedural types are implemented as delegates. If you want to reference a method of an instance object (see Classes and objects), you need to add the words of object to the procedural type name. For example 

type
  TMethod      = procedure of object;
  TNotifyEvent = procedure(Sender: TObject) of object;
These types represent method pointers. A method pointer is really a pair of pointers; the first stores the address of a method, and the second stores a reference to the object the method belongs to. Given the declarations 

type
  TNotifyEvent = procedure(Sender: TObject) of object;
  TMainForm = class(TForm)
    procedure ButtonClick(Sender: TObject);
     ...
  end;
var
  MainForm: TMainForm;
  OnClick: TNotifyEvent
we could make the following assignment. 

OnClick := MainForm.ButtonClick;
Two procedural types are compatible if they have 

the same calling convention, 
the same return value (or no return value), and 
the same number of parameters, with identically typed parameters in corresponding positions. (Parameter names do not matter.) 
On Win32, procedure pointer types are always incompatible with method pointer types, but this is not true on the .NET platform. The value nil can be assigned to any procedural type. 

Nested procedures and functions (routines declared within other routines) cannot be used as procedural values, nor can predefined procedures and functions. If you want to use a predefined routine like Length as a procedural value, write a wrapper for it: 

function FLength(S: string): Integer;
          begin
            Result := Length(S);
          end;
Procedural Types in Statements and Expressions
When a procedural variable is on the left side of an assignment statement, the compiler expects a procedural value on the right. The assignment makes the variable on the left a pointer to the function or procedure indicated on the right. In other contexts, however, using a procedural variable results in a call to the referenced procedure or function. You can even use a procedural variable to pass parameters: 

var
  F: function(X: Integer): Integer;
  I: Integer;
  function SomeFunction(X: Integer): Integer;
    ...
  F := SomeFunction;    // assign SomeFunction to F
  I := F(4);            // call function; assign result to I
In assignment statements, the type of the variable on the left determines the interpretation of procedure or method pointers on the right. For example, 

var
  F, G: function: Integer;
  I: Integer;
  function SomeFunction: Integer;
    ...
  F := SomeFunction;      // assign SomeFunction to F
  G := F;                 // copy F to G
  I := G;                 // call function; assign result to I
The first statement assigns a procedural value to F. The second statement copies that value to another variable. The third statement makes a call to the referenced function and assigns the result to I. Because I is an integer variable, not a procedural one, the last assignment actually calls the function (which returns an integer). 

In some situations it is less clear how a procedural variable should be interpreted. Consider the statement 

if F = MyFunction then ...;
In this case, the occurrence of F results in a function call; the compiler calls the function pointed to by F, then calls the function MyFunction, then compares the results. The rule is that whenever a procedural variable occurs within an expression, it represents a call to the referenced procedure or function. In a case where F references a procedure (which doesn't return a value), or where F references a function that requires parameters, the previous statement causes a compilation error. To compare the procedural value of F with MyFunction, use 

if @F = @MyFunction then ...;
@F converts F into an untyped pointer variable that contains an address, and @MyFunction returns the address of MyFunction. 

To get the memory address of a procedural variable (rather than the address stored in it), use @@. For example, @@F returns the address of F. 

The @ operator can also be used to assign an untyped pointer value to a procedural variable. For example, 

var StrComp: function(Str1, Str2: PChar): Integer;
   ...
@StrComp := GetProcAddress(KernelHandle, 'lstrcmpi');
calls the GetProcAddress function and points StrComp to the result. 

Any procedural variable can hold the value nil, which means that it points to nothing. But attempting to call a nil-valued procedural variable is an error. To test whether a procedural variable is assigned, use the standard function Assigned: 

if Assigned(OnClick) then OnClick(X);
See Also
Data Types 

Simple Types 

String Types 

Structured Types 

Pointers and Pointer Types 

Variant Types 

Type Compatibility and Identity 

Declaring Types 

Variables 

Declared Constants

Copyright(C) 2008 CodeGear(TM). All Rights Reserved. 
What do you think about this topic? Send feedback!  

#5


详细的就是, 你可以指定这么一个类型的变量, 比如testfunc: T_ic_init
这个时候只要设置好testfunc的值, 就可以按照你定义的那样去调用, 比如
testfunc(1,2);