手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>delphi>列表

Delphi2005学习笔记2——Using Platform Invoke with Delphi 2005

来源:互联网 作者:西部数码 时间:2008-04-09
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!
Pointer to pointer type (^PInteger) IntPtr IntPtr When working with arrays and strings in structures, the MarshalAs attribute is used to describe additional information to the default marshaler about the data type. A record declared in Delphi 7, for example:
type
  TMyRecord = record
    IntBuffer: array[0..31] of Integer;
    CharBuffer: array[0..127] of Char;
    lpszInput: LPTSTR;
    lpszOutput: LPTSTR;
  end;
Would be declared as follows in Delphi 2005:
type
  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  TMyRecord = record
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
    IntBuffer: array[0..31] of Integer;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    CharBuffer: string;
    [MarshalAs(UnmanagedType.LPTStr)]
    lpszInput: string;
    lpszOutput: IntPtr;
  end;
The above declarations assume that the strings contain platform dependant TChar’s (as commonly used by the Win32 API). It is important to note that in order to receive text in lpszOutput, the Marshal. AllocHGlobal method needs to be called before passing the structure to an API function. A structure can contain structures, but not pointers to structures. For such cases an IntPtr must be declared, and the Marshal. StructureToPtr method used to move data from the managed structure into unmanaged memory. Note that StructureToPtr does not allocate the memory needed (this must be done separately). Be sure to use Marshal. SizeOf to determine the amount of memory required, as Delphi’s SizeOf is not aware of the MarshalAs attribute (in the example above, CharBuffer would be 4 bytes using Delphi’s SizeOf when it in fact should occupies 128 bytes on a single byte system). The following examples show how to send messages that pass pointers to a structure:
procedure SetRect(Handle: HWND; const Rect: TRect);
var
  Buffer: IntPtr;
begin
  Buffer := Marshal.AllocHGlobal(Marshal.SizeOf(TypeOf(TRect)));
  try
    Marshal.StructureToPtr(TObject(Rect), Buffer, False);
    SendMessage(Handle, EM_SETRECT, 0, Buffer);
  finally
    Marshal.DestroyStructure(Buffer, TypeOf(TRect));
  end;
end;

procedure GetRect(Handle: HWND; var Rect: TRect);
var
  Buffer: IntPtr;
begin
  Buffer := Marshal.AllocHGlobal(Marshal.SizeOf(TypeOf(TRect)));
  try
    SendMessage(Handle, EM_GETRECT, 0, Buffer);
    Rect := TRect(Marshal.PtrToStructure(Buffer, TypeOf(TRect)));
  finally
    Marshal.DestroyStructure(Buffer, TypeOf(TRect));
  end;
end;
It is important to call DestroyStructure rather than FreeHGlobal if the structure contains fields where the marshaling layer needs to free additional buffers (see the documentation for DestroyStructure for more details). Advanced topics Working with unmanaged API’s it is not uncommon to need to convert a byte array into a structure (or retrieve one or more fields from a structure held in a byte array), or vice versa. Although the

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!