在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对于快速开发数据库应用方面的确有其独特的优势,但遇到需要用第三方语言来扩展功能的时候,就显得力不从心了。
分享到:
相关推荐
例如,给定的标题 "Pb字符串中的中文和英文(含符号)拆分" 描述了一个需求:将像 '中字A文C' 这样的字符串拆分为 '中字文' 和 'AC'。为了实现这一功能,我们可以创建一个自定义函数,例如 `uf_split_str_enorcn()`。 ...
- `ll_i`:循环变量,用于遍历字符串中的每一个字符。 2. **空字符串检查**: - 在函数开始前,先检查传入的字符串是否为空或者未定义,如果是,则直接返回空字符串。 3. **全角转半角逻辑**(当`iFlag`为1时)...
1. Asc():功能是得到字符串第一个字符的 ASCII 码整数值。例如:Integer li_Asc = Asc("ABC"); 2. Char():功能是将字符串的第一个字符、Blob 变量的第一个值、或一个整数转换成字符。例如:Char lc_Char = Char...
3. **创建自定义对象**: 在PB12.5中,创建一个新的用户对象(User Object),这个对象将封装对DLL的调用。在对象中定义必要的方法,如`ComputeMD5`,用于执行MD5加密。 4. **声明DLL函数**: 在自定义对象中,使用`...
- **半角字符**:通常指一个字符占用一个字节的空间,适用于英文、数字以及标点符号等,一般在ASCII码中表示。 - **全角字符**:每个字符占用两个字节的空间,主要应用于东亚语言环境下,为了保持视觉上的统一美观而...
1. **创建用户对象**: 在PowerBuilder的用户对象画板中创建一个包含数据窗口控件的用户类。 2. **保存用户对象**: 将用户对象保存到对象数据库中。 3. **运行时打开用户对象**: 使用`OpenUserObject()`函数在运行时...
在上述代码中,`Space(255)`函数用于分配一个长度为255的空字符串,`messagebox`用于显示结果,而`st_2.text`将返回的姓名信息赋值给PB的文本框控件。 需要注意的是,当DLL函数与PB的数据类型不匹配时,可能需要...
2. **PB_runtime**:这是一个特定于PB2017的环境变量,它指向PB的运行时库所在的目录。确保这个路径正确,否则可能会导致运行时错误。 3. **PB_NWDISTDIR**:这个环境变量用于指定PowerBuilder的网络发布目录,如果...
根据给定的信息,本文将详细解释“PB用于CRC16校验的函数方法”,包括创建结构体、定义全局变量、创建字符串分割函数、创建异或计算函数以及CRC16校验函数。 ### 1. 创建结构体以存储CRC字典列表数据 在编程语言...
- 对于输入字符串中的每一个字符,获取其ASCII值并进行处理: - 如果ASCII值大于等于32,则从ASCII值中减去32后乘以其位置序号加入总和。 - 如果ASCII值小于32,则加上64后乘以其位置序号加入总和。 - 计算总和...
为了实现在PB环境中生成CODE128B条形码,我们需要编写一个函数`f_getcode128`,该函数接收一个字符串作为输入,并返回一个符合CODE128B规范的条形码字符串。以下是具体实现的代码示例及解释: ```pb // 函数定义 ...
首先,我们看到函数的初始化部分定义了多个字符串变量,用于存储人民币数字对应的汉字字符以及临时存储转换过程中的结果。这些变量包括`jet`、`dxs`、`xxs`、`jew1`到`jef`,以及`ls`和`lss`。`jet`变量用于存储输入...
1. Asc() 函数:得到字符串第一个字符的 ASCII 码整数值。 语法:Asc ( string ) 参数: * string:要得到第一个字符 ASCII 值的字符串 返回值:Integer 函数执行成功时返回 string 参数第一个字符的 ASCII 值...
2. **分配缓冲区**:由于`GetModuleFileNameA`会将文件路径写入到我们提供的缓冲区,所以我们需要预先分配一个足够大的字符串变量来存放路径,比如: ```powerbuilder String szFilePath[256] // 假设路径最长255个...
4. **返回结果**:循环结束后,`ls_return`变量中存储的就是转换后的中文大写字符串,将其作为函数的返回值。 #### 示例代码 ```pb String ls_num[] = {'һ', '二', '三', '四', '五', '六', '七', '八', '九', '...
"demo.pbl"可能是一个示例程序库,包含了一些演示如何使用PB基类对象的代码。通过查看和分析这些示例,开发者可以更好地理解和学习如何在实际项目中应用PB的基类对象。这可能涵盖从简单的数据操作到复杂的业务逻辑...
新增自动删除每行代码前面和后面以某个字符串为标记,在此 标记之前和之后的代码语句,类似于 Trim, LeftTrim, RightTrim 5.5 新增 PBDataWindow.exe,处理从 PBL 里选择 DataWindow 自动 生成和结构体、变量,...