NAG DLL 与 PowerBuilder

说明

外部函数指的是不以 PowerScript 所开发而成的函数且以 DLL 型态储存,如同在 Macintosh 与 UNIX 环境的共享库。您可以调用其他语言所开发而成的动态链接库。 当您在脚本中使用外部的函数前,您必须先声明。可以透过以下两种方式声明:

  1. 全局外部函数: 可在应用程序任何地方使用。
  2. 区域外部函数: 可被使用在特定的窗口、选单、用户对象或用户定义函数中。这些函数属于对象定义的一部份,可以在对象或脚本中使用。也可以在其他脚本中使用到这些函数。

PowerBuilder for Unicode

如果您的外部程序将被使用于 PowerBuilder for Unicode 环境中,则函数必须要以 Unicode 方式编译。所有的字符串必须以 Unicode 字符串传递。如果您调用 Windows API 函数,也必须使用此函数的 Unicode 版本。例如:使用 FindWindowW (W for wide) 取代 FindWindowA (A for ANSI)。

语法

外部函数语法

使用以下语法声明外部函数:

{ access } FUNCTION returndatatype name ( { { REF }
 datatype1 arg1,	..., { REF }
 datatypen argn } )
 LIBRARY "libname"	ALIAS FOR "extname"

外部子程序语法

您也可以声明外部的子程序 (与外部函数相同,除了其不会回传数值):

{ access } SUBROUTINE name ( { { REF }
datatype1 arg1, ...,	{ REF } datatypen argn } )
 LIBRARY "libname"	ALIAS FOR "extname"

参数说明

Access (选项) (区域外部函数),可以指定为 Public、Protected 或 Private 来设定存取的层级。

FUNCTION 或 SUBROUTINE 关键词用来指定调用的类型,决定传回值如何处理。如果有回传值,则需要声明为 FUNCTION;若回传为 VOID 或不传回值,则指定为 SUBROUTINE

returndatatype: 函数传回的资料型别
name:在 DLL 中的函数名称
REF:指定传递参数。函数可以在 arg 中储存为数值,由 PowerBuilder 脚本引用
datatype arg:函数或子程序的参数资料型别。必须符合 DLL 中的函数参数定义。每个资料型别前面会以 REF LIBRARY "libname" 表示
LIBRARY 关键词包含了 DLL 的名字。Microsoft Windows DLL 通常有 DLL 或 EXE 的扩展名,而在 Macintosh 中通常动态库以 DLL 或 EXEOn 扩展名。在 UNIX 环境中 libname 是共享库,通常会有扩展名。
Naming: 在每个平台中取代不同的命名原则,你可以使用相同的函数名称。以引号指名算法库名称,且不能加上路经。算法库必须在执行时能够被参考到

ALIAS FOR "extname" (选项)

紧接着的字符串是在 DLL 中定义的函数名称。若在 DLL 中的函数名称并不是你想要在脚本中使用的名字,或者其并不是 PowerScript 的合法接受名,您必须指定 ALIAS FOR "extname" 来建立一个 PowerScript 与外部函数名相对应的别名。

使用方式

当声明一个区域外部函数时,可以同时指定存取的层级:
取用层级

如何使用区域的外部函数

Public
在应用系统中任何的脚本

Private Scripts
在函数被声明的对象中。但是不能在对象的继承者中使用

Protected Scripts
在函数或其后的声明中
在区域外部函数使用 access 关键词

执行中 DLL 如何置放

为了要能让 PowerBuilder 应用程序能在各 Windows 平台中执行,DLL 必须置于以下其中之一的目录中:

  • 目前路径
  • Windows 目录
  • Windows 系统子目录
  • 在 path 环境变量中

在 Macintosh 环境中,共享库通常储存在 Extensions 目录中。

在 UNIX 环境,更新 LD_LIBRARY_PATH 环境变量,加上共享库所在位置。

示例

以下的示例是由 PowerBuilder 所提供,外部函数在 u_external_function_win32 对象中被声明为局部外部函数。调用函数的脚本是对象函数,但是因为是相同的用户对象,所以不需要使用对象的方式进行调用。

示例 1

这些声明提供 PowerBuilder 调用在 WIN32 DLL WINMM.DLL 中的音乐:

//playsound

FUNCTION boolean sndPlaySoundA (string SoundName, uint Flags) LIBRARY "WINMM.DLL"

FUNCTION uint waveOutGetNumDevs ( ) LIBRARY "WINMM.DLL"

Unicode versions of Windows API calls Use the Unicode version of the
function name in PowerBuilder for Unicode. For example, use sndPlaySoundW
instead of sndPlaySoundA.

The declarations for WIN16 versions of the functions are similar:

//playsound

FUNCTION boolean sndPlaySound (string SoundName, uint Flags) LIBRARY "mmsystem.dll"

FUNCTION uint waveOutGetNumDevs ( ) LIBRARY  "mmsystem.dll"

A function called uf_playsound in the examples50 application provided with PowerBuilder calls the external functions. Uf_playsound is called with two arguments (as_filename and ai_option) that are passed through to sndPlaySoundA. Values for ai_option are as defined in the Win32 documentation, as commented here:

//Options as defined in mmystem.h.

//These may be or'd together.

//#define SND_SYNC 0x0000

//play synchronously (default)
//#define SND_ASYNC 0x0001

//play asynchronously

//#define SND_NODEFAULT 0x0002

//don't use default sound

//#define SND_MEMORY 0x0004

//lpszSoundName points to a memory file

//#define SND_LOOP 0x0008

//loop the sound until next sndPlaySound

//#define SND_NOSTOP 0x0010

//don't stop any currently playing sound

uint lui_numdevs

lui_numdevs = WaveOutGetNumDevs( )

IF lui_numdevs > 0 THEN
         sndPlaySoundA(as_filename,ai_option)
         RETURN 1

ELSE
         RETURN -1

END IF


示例 2
声明 Win32 GetSysColor 函数:

FUNCTION ulong GetSysColor (int index) LIBRARY "USER32.DLL"

此叙述调用外部函数。返回在 Win32 所定义输入参数的颜色值:

RETURN GetSysColor (ai_index)


示例 3
声明 Win32 GetSysColor 函数:

FUNCTION int GetSystemMetrics (int index) LIBRARY "USER32.DLL"

此叙述调用外部函数取得屏幕高度:

RETURN GetSystemMetrics(1)

此叙述调用外部函数取得屏幕宽度:

RETURN GetSystemMetrics(0)