Database 版 (精华区)

发信人: mengy (LEAR DLLS 命令时,将从内存中清除), 信区: Database
标  题: Visual FoxPro扩展程序库的编写要点
发信站: 哈工大紫丁香 (2000年12月30日19:04:00 星期六), 转信

Visual FoxPro扩展程序库的编写要点
 
  摘要:本文介绍用C/C++编制Visual FoxPro扩展程序库的基本要点,并给出一
些参数传递的例子。
  关键词:Visual FoxPro扩展程序库

  Visual FoxPro的扩展程序库由C或C++编写,可以访问Visual FoxPro的“应用
程序接口”(API),大大扩展了Visual FoxPro的原有功能。本文即介绍编制扩展程
序库的基本要点。
  编制扩展程序库有一定的软件要求。首先,由于Visual FoxPro是一个32位的
应用程序,所以必须使用一32位编译器来连编该程序库,笔者推荐使用
Microsoft VisualC++TM4.1版。其次需要Visual FoxPro“应用程序接口”的头文
件(PRO_EXT.H)以及导入库(WINAPIMS.LIB),这两个文件均在Visual FoxPro的
API子目录下。
  对于有C语言编程经验的程序员来说,写扩展程序库的难点在于要搞清:扩展
程序库本身的框架、数据类型和数据结构以及扩展程序库与Visual FoxPro环境的
数据交换约定。下面主要介绍这三点。

  一、 扩展程序库的基本结构

  程序库由四部分组成:

  1、#include 语句

#include <pro_ext.h>;
  2、函数定义
void Function _ Name (ParamBlk*parm)
{
\\函数代码
}
  3、FoxInfo结构
FoxInfo myFoxInfo[]\{
{"FUNCTION_N",(FPFI)Function_Name,
ParmCount,ParmTypes},
};
  FoxInfo结构用于在Visual FoxPro和库之间传递函数名和参数描述信息。“
myFoxInfo"为FoxInfo型的变量。注意在该数组中可以包含多个FoxInfo结构行。
ParmCount指定在ParmTYpes字符串中描述的参数个数,或者下列标志值之一:

值 说明 
INTERNAL 指明该函数不能直接从Visual FoxPro调用 
CALLONLOAD 指明该函数在加载时调用。 
CALLONUNLOAD 指明该函数的卸载库,或发出VisualFoxPro的QUIT命 令时调用 


   注:CALLONLOAD和CALLONUNLOAD均不能调用那些返回结果给Visual FoxPro的
函数。

ParmTYpes描述每个参数的数据类型。下表列出ParmTYpes的有效值。



值 描述 
““ 无参数 
“?” 能传递任意类型 
“C” 字符型参数 
“D” 日期型参数 
“I” 整型参数 
“L” 逻辑型参数 
“N”  数值型参数 
“R” 引用 
“T” 日期时间型参数 
“Y” 货币型参数 


  4、Foxtable 结构
FoxTable myFoxTable={
(FoxTable *)0,sizeof(myFoxInfo) /
sizeof(FoxInfo),myFoxInfo
}
  该结构第一个参数是Visual FoxPro内部使用的一个指针,必须初始化为0;第
二个参数是该程序库定义的Visual FoxPro外部例程数目;第三个参数实际为该程
序库FoxInfo结构的变量名。如读者的FoxInfo型变量名为myFoxInfo,建议读者直
接使用上面这个例子。

  二、Visual FoxPro API数据类型与数据结构

  1、数据类型
  Visual FoxPro API定义的数据类型见下表:



数据类型 说明 
EDLINE 用于编辑窗口中打开的文件,指明文件中某一行的行号,首行为1。 
EDPOS 用于编辑窗口中打开的文件,指明文件中某个字符的偏移位置 。 
FCHAN 文件通道。每个由Visual FoxPro打开的文件,或通过API用 _FCreate()和
_FOpen()打开的文件,都被分配一个FAHAN FPFI 指向一个返回一个整数值的函数
的32位指针。 
ITEMID 为菜单中某一命令指定的唯一标识。 
MENUID 指定给一个菜单的唯一标识。 
MHANDLE 一个唯一标识,每一个由Visual FoxProw分配的内存块,或通过API用
_AllocHand()分配的内存块都具有这样一个标识。可以使用_HandToPtr()返回引用
到它的指针。 
NTI 名称表索引。每个内存变量和表字段的名称在该表中都有一项 。 
WHANDLE 窗口句柄。每一个由Visual FoxPro打开的窗口,或者通过API 用
_Wopen()打开的窗口都有这样一个唯一的标识。 


  2、数据结构
Visual FoxPro API定义的数据结构见下表:



数据类型 结构说明 
EventRec 一个结构,用于描述在某个给定的时刻系统正在进行的操作。 
FoxInfo 前面已介绍 
FoxTable 前面已介绍 
Locator 在“数据交换”中详细介绍 
ParamBlk 在“数据交换”中详细介绍 
Parameter 在“数据交换”中详细介绍 
Point 一个结构,定义了屏幕上一个点的水平和垂直坐标。坐标按行号和列号指定
。 
Rect 一个结构,定义了屏幕上一个矩形的坐标。该矩形的左上角由 (top,left)定
义,右下角由(bottom-1,right-1)定义。坐标按 行号和列号指定。 
Value 在“数据交换”中详细介绍 

   
  三、扩展程序库与Visual FoxPro环境的数据交换

  扩展程序库与Visual FoxPro环境的数据交换分两部分:程序库从Visual 
FoxPro接受参数;程序库返回值给Visual FoxPro。
  1、扩展程序库从Visual FoxPro接受参数
  程序库中定义的函灵敏实际上只接受一个参数:一个指向参数块的指针。该参
数块在ParamBlk结构中定义,保存了有关Visual FoxPro函数传递来的参数的全部
信息。所以函数申明必须是如下格式:
void FunctionName(ParamBlk*parm)
ParamBlk结构定义包含在PRO_EXE.H中:
/*库函数的参数列表*/
typedef struct{
short int pCount:/*传递的参数个数*/
Paramneter[1]:/* pCount个参数*/
}ParamBlk;
  包含在ParamBlk结构中的parameter数据类型是一个含有一个Value结构和一个
Locator结构的联合。当函数被Visual FoxPro调用时,可用这些结构来访问传递给
它的参数。Parametet数据类型、Value结构和Locator结构都在PRO_EXT.H中定义:

/*给库函数的参数*/
typedefunion{
Value val;
Locator loc;
}Parameter
/*一个表达式的值*/
typedef struct{
char ev_type;
char ev_padding;
short ev_width;
unsigned ev_length;
long ev_long;
double ev_real;
ccy ev_currency;
MHANDLE ev_handle;
ULONG ev_object;
}value;
/*一个表或内存变量的引用*/
typedef struct{
char 1_type;
short 1_where
l_NTI,
l_offset,
l_subs,
l_subl,l_sub2;
}Locator
  Visual FoxPro程序可按值或引用将变量传给库函数。默认时,内存变量的传
递方式取决于SETUDFPARMS。其他变量(比如数组或字段)和表达通过值来传递。强
制一个变量按引用传递,可在该变量引用之前加上@操作符。要强制一个变量按值
传递,可把该变量用括号括起来。每个参数的信息保存在一个Value或者一个
Locator结构中,按值的调用由value结构处理;按引用的调用则由Locator结构处
理。下表说明了Value结构中各域与参数类型的对应关系:
数据类型 ev_type ev_width ev_length ev_long
ev_real ev_handle ev_currency
字符型 ‘C’ 字符串长度 字符串的
MHANDLE
数值型 `N' 显示宽度 小数位 双精度
整型 `I’ 显示宽度 长整型
日期型 `D' 日期
日期时间型 `T' 日期+(秒/86400.0)
货币型 `Y' 显示宽度 货币值
逻辑型 `L'
备注型 `M' FCHAN 0或1 备注字 备注字段编
段长度 移量
通用型 `G' FCHAN 备注字 备注字段编
段长度 移量
Null `O' 数据类型

  下表说明了Locator结构中各域的含义:



结构元素 用法 
l_type  `R' 
l_where -1表示内存变量,或为一工作区号 
l_NTI 名称表索引 
l_offset 字段偏移量 
l_sub0 为内存变量,或为一下标数(如是数组) 
l_sub1 第一下标(如果数组) 
l_sub2 第二下标(如果维数组) 


  下面是接收参数的几个例子:
(1)接收一个数型参数
long long_var;
long_var=pann->P[0].Val.ev_long;
(2)接收一个日期型参数
double date;
date=parm->P[0]val.ev_real;
(3)通过传值方式接收一个字符串
char buf[256];
MHANDLE pvar;
pvar=parm->P[0]val.ev_handle;
_HLock(pvar); 
_MemMove(buf,HandToPtr(pvar),parm->;
P[0].val.ev_length)
HUnlock(pvar)
为确保该字符串以‘\0’结尾,可令buf[255]=‘\0’;
(4)通过引用方式接收一个字符串
char buf[256];
Value val,*pval;
Locator *loc;
int errcode;
loc=&parm->p[0].loc;
pval=&val;
if(((errcode=_lode(loc,pvar))!=0);
_Error(-errcode);
//为确保以‘\0’结尾,要加1字节的空间
if (!_SetHandSize(pvar->ev_handle,pvar->
ev_length+1))
_Error(182)_;
//字符串尾加‘\0’
*((char*)_HandToPtr(pvar->ev_handle)+pvar->
ev_length)=`\0'
_HLock(pvar);
_MernMove(buf,_HandToPtr(pvar),pvar->
ev_length+1

_HUnLock(pvar)
  2、返回值给Visual FoxPro
返回值给Visual FoxPro,可以使用在PRO_EXT.H中说明的API函数;
函数说明
RetCHar(char*string) 返回一个以null终止的字符串。
_RetDateStr(char*string) 返回一个日期值。日期格式是mm/dd/yy[yy]。
_RetDateTimeStr(Char*string) 返回一个日期时间值。格式为mm/dd/yy[yy]
hh:mm:ss。
_RetFloat(double flt int width int dec 返回一个浮点值。
_RetInt(longival int width) 返回一个整型值
_RetCurrency(CCY cval int width) 返回一个货币值。
_RetLogical(int flag) 返回一个逻辑值。0为“假”;非0为真。
_RetVal(Value*val) 传递一个完整的Visual FoxPro Value结构构;利用此函数,
除备 注之外的任何Visual FoxPro数据类型都可返回。必须调用 _RetValo来返回
一个包含内嵌null字符的字符串,或返回一个 NULL值。
  这些API函数十分好用,但有一个缺点;一个函数只能有一个返还信息。作为
一个C语言程序员,对函数原型中形参的作用一定不陌生。究其根本,形参其实指
示了一片内存区域,被调函数对该区域操作。函数结束后,信息保留在此内存区域
,“返还”给主调函数。Visual FoxPro中按引用传递参数与之很相似。笔者根据
此原理,成功的编写了几个引用返还信息的子程序。见示例;
(1)通过引用方式返回一个整型数
Locator*lo
Value temp
int errorcode
lo=&parm->p[0].loc
temp.ev_long=num//num
temp.ev_type=`I'
temp.ev_width=10;
if((errorcode=Stroe(lo,&temp))!=0
_Error(-errorcode)
(2)通过引用方式返回一个字符串
Locator*lo;
Vahue temp
int errcode
lo=&parm-P[0].loc
temp.ev_type=`C',
temp.ev_length=tength;//length为字符串长度
if((temp.ev_handle=_AllocHand(length)=0)
(Error(182)//内存不够
_Hlock(temp.ev_handle;//string为返回字符串指针
_MemMove(HandToPtr(temp.ev_handle)stringlength);
_HUnLock(temp.ev_handle);
if((errorcode=_store(lo,&temp))!=-
_Error(-errorcode)

  以上只介绍了编制Visual FoxPro扩展程序库的基本知识,读者如想处理自己
的实际问题,还需要根据情况仔细分析。 
 
转载自Fox爱好者天堂 (文/井卫军) 
 
返回首页
 


 

--

       大海无边天做岸
               山登绝顶我为风

※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.227.121]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.581毫秒