在PB中,经常会需要调用一些动态库(DLL)来实现功能的扩展,但DLL一般都是C语言或Delphi语言写的,常常会使用指针,给出的参数也常常是指针形式的。虽然PB中可以加上REF关键字来指明传递的是参数地址,但实际使用中却往往会出一些意想不到的结果,我最近在调用一个DLL时,使用REF传递一个字符串给DLL,但最后DLL取到的却是一串乱码,这说明传给DLL的地址错了,DLL取到了别的内存块的数据,此时,PB只能望针兴叹了。
其实,在有些时候,我们还是可以变通地使用一些其他办法来迂回地操作指针的。下面是我实际使用的通过Windows API来取到字符串地址的方法:
一、首先声明一个API函数:
Function long lstrcpy(ref string Destination, ref string Source) library "kernel32.dll" ALIAS FOR "lstrcpy;ansi";
二、再调用上面的函数来得到字符串地址:
String ls_src, ls_dst
long ll_address
ls_src = "PB中如何得到一个字符串变量的地址"
ls_dst = space(255)
ll_address=lstrcpy(ls_dst, ls_src )
这样,ll_address中得到的就是字符串ls_dst的地址了,我有一个C语言写的DLL,其中一个函数是这样的:
void __stdcall ChangePrinterSetting(LPTSTR pCustomFormName, SIZEL* FormSize);
按照正常的方式,在PB里应该这样声明并调用:
public FUNCTION Integer ChangePrinterSetting(REF string formName, REF STRU_SIZEL size) LIBRARY "PrnSet.dll" ALIAS FOR "ChangePrinterSetting;ansi";
String ls_fromName
STRU_SIZEL size;
ls_fromName = "我的表单格式"
size.cx = 100000
size.cy = 200000
ChangePrinterSetting(ls_fromName, size)
但这样调用,实际运行发现,DLL中取到的是乱码,说明通过REF关键字传递给DLL的参数地址错了,于是我改成这种方式:
public FUNCTION Integer ChangePrinterSetting(long formName, REF STRU_SIZEL size) LIBRARY "PrnSet.dll" ALIAS FOR "ChangePrinterSetting;ansi";
String ls_fromName, ls_temp
STRU_SIZEL size;
ls_fromName = "我的表单格式"
ls_temp = space(255)
ll_address=lstrcpy(ls_temp, ls_fromName)
size.cx = 100000
size.cy = 200000
ChangePrinterSetting(ll_address, size)
这样,DLL里就取到了正确的中文字符串。这样多写了几行代码,保存了参数正确传递,也算是没有办法的办法吧。
总得说来,PB对于快速开发数据库应用方面的确有其独特的优势,但遇到需要用第三方语言来扩展功能的时候,就显得力不从心了。