PB的扩展DLL开发(超级篇)(三)

PB的扩展DLL开发(超级篇)(三)

(PB史上第一次开放的开发技术)

最核心的一个结构,OB_THIS ,这个在上一章已做过介绍。本章介绍OB_DATA 这个结构。这个结构的重要程度仅次于OB_THIS。

OB_DATA是PB里各种类型的数据参数在DLL里的存在形式。你在PB里写的代码例如

Int I; long n;string ls_text; window w;….. 这些,对照到C内部的映射,它们全部都是一个OB_DATA指针。在这个函数里__declspec(dllexport) DWORD __stdcall FuncName(POB_THIS obThis,int nArgCount) ,我们已经知道obThis指向的是一个VM或者session,另一个参数是nArgCount,它指明了参数个数。那参数在哪呢?obThis->evaled_arglist 这个结构成员保存的就是参数列表。我们可以这样:

POB_DATA lpArgs = (POB_DATA) obThis->evaled_arglist;

For(int i=0;i< nArgCount;i++)

{

        POB_DATA lpArg = lpArgs[i];

         ……

}

(实际写代码过程中,一般不会象上面这样使用,这个方法太不安全了。更好的方法会在下面章节里介绍。)

来取得一个在PB代码里传入 进来的参数。这样不管多少个参数,都可以能取得到。

这里说一下PB里的不固定参数,比如有这样一个函数:

function int Printf(string strFormat,...) system library "PbJson.dll" alias for "Printf"

就是以 … 为声明方式来传递不固定参数。对DLL内部来说,可以把所有参数给取出来,与实际参数名称没有任何关系。

先看看OB_DATA的声明:

                   typedef struct ob_data

                   {

                            OB_VALUE                     val;

                            OB_INFO_FLAGS             info;                                      // Data node info flags

                            OB_CLASS_ID                           type;                                               // Data Type

          } OB_DATA, FAR* POB_DATA;

它的项目相关成员和结构的声明:

typedef USHORT      OB_BASE_ID;

typedef OB_BASE_ID        OB_CLASS_ID, FAR* POB_CLASS_ID;

typedef USHORT                        OB_INFO_FLAGS, FAR* POB_INFO_FLAGS;

                   typedef union ob_value

                   {

                            SHORT                                int_val;                     // Integer value

                            FLOAT                                 fl_val;                                   // Float value

                            PVOID                                  ptr;                             // Ptr to value

                            OB_CONST_REF              const_ref;                            // Constant value

                            PVOID                                  ob_inst;                       // There for compatibility, ptr should be used instead

                            USHORT                             id;                                          // Id value

                            USHORT                             uint_val;                     // Unsigned integer

                            LONG                                   long_val;                    // Long integer

                            ULONG                                ulong_val;                           // Unsigned Long integer

                            BYTE                                   byte_val;                    // Byte value

          } OB_VALUE, FAR* POB_VALUE;

OB_DATA这个结构,有3个成员:

1OB_VALUE val; 这是一个union 体,它的大小是8个字节。它实际保存的是PB变量或参数的值或者指针,这些值保存PB里的值,它的指针是由专用内存管理函数从自己的堆上分配,可以由PB自己管理,自动释放。这个值的具体的类型由OB_CLASS_ID type决定。

3OB_CLASS_ID 就一个 ushort 的类型,也就是一个整值,它是可以是下列这些值:

#define NO_TYPE 0

#define INT_TYPE 1

#define LONG_TYPE 2

#define FLOAT_TYPE 3

#define DOUBLE_TYPE 4

#define DEC_TYPE 5

#define STRING_TYPE 6

#define BOOL_TYPE 7

#define ANY_TYPE 8

#define UINT_TYPE 9

#define ULONG_TYPE 10

#define BINARY_TYPE 11

#define DATE_TYPE 12

#define TIME_TYPE 13

#define DATETIME_TYPE 14

#define CURSOR_TYPE 15

#define PROC_TYPE 16

#define BASIC_TYPE 17

#define CHAR_TYPE 18

#define HANDLE_TYPE 19

#define LONGLONG_TYPE 20

#define BYTE_TYPE 21

#define NUMBER_OF_ottypes 22

看到这些定义,自然就联想到PB的那些变量类型了 int long ulong string 之类,没错,就是与PB的类型一一对应。只不过,有些类型的值它是直接放在ob_value里的,比如 INT_TYPE 就可以直接取 lpArg->int_val ,LONG_TYPE 可以直接取 lpArg->long_val 。但有些值它存的是指针,比如 STRING_TYPE、BINARY_TYPE、DECI_TYPE、LONGLONG_TYPE,这些是以指针方式保存,得到指针后需要自己转换使用。

看最后一项:NUMBER_OF_ottypes 22,最多只有22个?显然不是的。

***这里要注意一下:它还有个PVOID ob_inst成员。当OB_CLASS_ID type 的值大于 22时,它是一个对象的实例句柄。在PB里,你的各种对象实例,window lw; commandbutton btn; datawindow dw ; datastore ds 这些,传进来 ,它们只有一个类型:OB_CLASS_ID,实例句柄保存在 ob_inst这个成员里面这里成员使用的是PVOID类型,实际上,它有个专门的定义类型OB_INST_ID,它的定义是这样的typedef PVOID  OB_INST_ID

3、OB_INFO_FLAGS info。这个成员是干嘛的?开始的时候,我也迷糊好久,后来也没全弄清楚。

比如有个字符串传进来了:

PB: string str; str = “hello”;

DLL里这样取:TCHAR *text = (TCHAR *)lpArg->ptr_val;这样没问题。

如果PB: string str; setnull(str);

DLL里这样取:TCHAR *text = (TCHAR *)lpArg->ptr_val;这样就可能有问题了,得到的 text 可能是个无效的指针。那我们怎么知道它是有效还是无效指针呢?那应该这样:

If(!(lpArg->info & DATA_NULLVAL_MASK))

{

         TCHAR *text = (TCHAR *)lpArg->ptr_val;

}

加上一个是不是空的判断。IS_NULL是这样定义的:#define DATA_NULLVAL_MASK 0x0001

所以, OB_INFO_FLAGS info应该是各种标志,空标志,引用标志,作用域标志等等。

OB_DATA 实在是设计得很巧妙的一个结构!

如果你对system library相关开发方式感兴趣,可到QQ群624409252共享里大自在的专用目录下下载DEMO。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值