前往Shuct.Net首页

Shudepb PB反编译专家长时间以来,为业内同类软件事实上的唯一选择.细节,彰显专业.态度,决定品质.

关于PowerBuilder的搜索

pb调用外部dll的问题(关于char* *)-CSDN论坛-CSDN.NET-中国最大的IT技术社区 --> 首页 论坛帮助 论坛牛人 论坛地图 CSDN > CSDN论坛 > PowerBuilder > API 调用 管理菜单 置顶 推荐 锁定 移动 编辑 删除 帖子加分 帖子高亮 结帖 发帖 回复 benjaminz pb调用外部dll的问题(关于char* *) [问题点数:200分,结帖人benjaminz] 不显示删除回复 显示所有回复 显示星级回复 显示得分回复 只显示楼主 收藏 benjaminz benjaminz 等级: 结帖率:100% 楼主 发表于: 2009-08-19 15:09:41 在一个项目中用到一个外部dll调用 在该dll中封装了如下一个函数 int dexee(CHAR* sno, CHAR* sman, CHAR* sgoods,CHAR* *message) 在pb中声明为 function int dexee(ref string sno,ref string sman,ref string sgoods,ref string message) liberay "aa.dll" 在调用的时候总是报错 error calling external function %s at 19 line in click event... 不知道有没有同学遇到过相同的问题,并解决了的呢?谢谢 更多 分享到: 相关主题推荐: function string 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 回复次数:22 jlwei888 jlwei888 等级: 结帖率:100% 4154 #1 得分:0 回复于: 2009-08-19 15:15:30 要定义成blob 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 benjaminz benjaminz 等级: 结帖率:100% #2 得分:0 回复于: 2009-08-19 15:47:13 jlwei888,您好,我按照你的说法换成blob还是不行,报错相同 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 wonderfulfeige wonderfulfeige 等级: 结帖率:89.47% #3 得分:0 回复于: 2009-08-19 16:15:55 你定义成ref string的时候,每个参数在传入的时候都要分配空间,如 sno=space(1024) sman=space(1024) sgoods=space(1024) message=space(1024) 你试试吧,最后一个参数message是char* *的哦! 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 benjaminz benjaminz 等级: 结帖率:100% #4 得分:0 回复于: 2009-08-19 16:20:55 引用 3 楼 wonderfulfeige 的回复:你定义成ref string的时候,每个参数在传入的时候都要分配空间,如 sno=space(1024) sman=space(1024) sgoods=space(1024) message=space(1024) 你试试吧,最后一个参数message是char* *的哦! 谢谢wonderfulfeige,我是提前用space分配了空间过去的,可是还是不行 就是最后一个char* *在捣乱啊 如果只是char* 我就不费这劲了 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 pcwe2002 pcwe2002 等级: 结帖率:97.01% #5 得分:0 回复于: 2009-08-19 16:25:42 这个应该和你封装有关了。C函数需要申明为_stdcall 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 benjaminz benjaminz 等级: 结帖率:100% #6 得分:0 回复于: 2009-08-19 16:27:42 引用 5 楼 pcwe2002 的回复:这个应该和你封装有关了。C函数需要申明为_stdcall 封装在这个dll里面不使用char* *的函数是可以调用的 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 31737951 31737951 等级: 结帖率:100% #7 得分:0 回复于: 2009-08-19 17:13:35 char* * 比较难啊 仿佛无解 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 31737951 31737951 等级: 结帖率:100% #8 得分:0 回复于: 2009-08-19 17:15:18 pb只能调用 已知数据类型 + 数据长度的 api char** 难啊 拐了好几个弯 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 benjaminz benjaminz 等级: 结帖率:100% #9 得分:0 回复于: 2009-08-19 17:28:23 引用 8 楼 31737951 的回复:pb只能调用 已知数据类型 + 数据长度的 api char** 难啊 拐了好几个弯 谢谢唐朝,唉,看看有没有解决过这个问题的大哥or大姐 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 31737951 31737951 等级: 结帖率:100% #10 得分:0 回复于: 2009-08-19 17:54:22 有个bt方法 用vc调用,然后跟踪 看看 哪个参数的 类型 和大体长度 然后在申明 blob 或者 char[] 来试试 调用前记得 分配空间 如 char lcc[1024] 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 msgtogcr msgtogcr 等级: 结帖率:88.89% #11 得分:0 回复于: 2009-08-19 20:32:42 PB中如何得到一个字符串变量的地址 转贴自听雨轩http://sheng.javaeye.com/blog/434727 在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对于快速开发数据库应用方面的确有其独特的优势,但遇到需要用第三方语言来扩展功能的时候,就显得力不从心了。 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 xys_777 xys_777 等级: 结帖率:73.47% 2更多勋章 #12 得分:0 回复于: 2009-08-19 21:15:52 是这个原因,我原来也遇到过这样的问题,加上stdcall就可以了 引用 5 楼 pcwe2002 的回复:这个应该和你封装有关了。C函数需要申明为_stdcall 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 kenshu kenshu 等级: 结帖率:98.33% #13 得分:200 回复于: 2009-08-19 23:00:36 引用楼主 benjaminz 的回复:在一个项目中用到一个外部dll调用 在该dll中封装了如下一个函数 int dexee(CHAR* sno, CHAR* sman, CHAR* sgoods,CHAR* *message) 在pb中声明为 function int dexee(ref string sno,ref string sman,ref string sgoods,ref string message) liberay "aa.dll" 在调用的时候总是报错 error calling external function %s at 19 line in click event... 不知道有没有同学遇到过相同的问题,并解决了的呢?谢谢 ref string message[]//在函数只是读取message,而不是写入的时候,成功读取里面的内容. VC6.0+PB7.0 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 kenshu kenshu 等级: 结帖率:98.33% #14 得分:0 回复于: 2009-08-19 23:15:42 //pb public function integer FAAA (ref string plibnames[]) library "DLLREF.dll" STRING AB [] AB[1] = "A1ASDF" AB[2] = "A2" AB[3] = "A3" FAAA(AB) //VC extern "C" long PASCAL EXPORT FAAA(char * *as_source){ long i,j; j = 3; for (i = 0;i<j;i++){ MessageBox(NULL,as_source[i],"",NULL); } return 0; } 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 msgtogcr msgtogcr 等级: 结帖率:88.89% #15 得分:0 回复于: 2009-08-19 23:31:35 楼上的方法很巧妙啊!用数组模拟指针的指针,学习学习! 另外只是读取的话,string(message, "address") 也可以 function int dexee(ref string sno,ref string sman,ref string sgoods,ref ulong message) liberay "aa.dll" 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 benjaminz benjaminz 等级: 结帖率:100% #16 得分:0 回复于: 2009-08-20 08:29:20 引用 10 楼 31737951 的回复:有个bt方法 用vc调用,然后跟踪 看看 哪个参数的 类型 和大体长度 然后在申明 blob 或者 char[] 来试试 调用前记得 分配空间 如 char lcc[1024] 唐朝,char型的数组是不能取到值的,还是谢谢了 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 benjaminz benjaminz 等级: 结帖率:100% #17 得分:0 回复于: 2009-08-20 08:31:20 引用 11 楼 msgtogcr 的回复:PB中如何得到一个字符串变量的地址 转贴自听雨轩http://sheng.javaeye.com/blog/434727 ? ? ? 在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对于快速开发数据库应用方面的确有其独特的优势,但遇到需要用第三方语言来扩展功能的时候,就显得力不从心了。 谢谢msgtogcr,你说的方法不能解决我的问题,呵呵 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 benjaminz benjaminz 等级: 结帖率:100% #18 得分:0 回复于: 2009-08-20 08:32:15 引用 12 楼 xys_777 的回复:是这个原因,我原来也遇到过这样的问题,加上stdcall就可以了 引用 5 楼 pcwe2002 的回复: 这个应该和你封装有关了。C函数需要申明为_stdcall 永生,不是这个问题,真的不是,呵呵 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 zhanghua_1228 zhanghua_1228 等级: 结帖率:100% #19 得分:0 回复于: 2009-08-20 09:06:13 ref string[] 用这个 因为指针的指针一般是个二维数组的指针,你可以用ref string数组来模拟这个二维数组 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 benjaminz benjaminz 等级: 结帖率:100% #20 得分:0 回复于: 2009-08-20 09:15:30 引用 14 楼 kenshu 的回复://pb public function integer FAAA (ref string plibnames[])? library "DLLREF.dll" STRING AB [] AB[1] = "A1ASDF" AB[2] = "A2" AB[3] = "A3" FAAA(AB) //VC extern "C" long PASCAL EXPORT FAAA(char * *as_source){ long i,j; j = 3; for (i = 0;i <j;i++){ MessageBox(NULL,as_source[i],"",NULL); } return 0; } 谢谢kenshu,使用你的方法可以成功的取得参数里面的内容,十分感谢! 结贴了 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 chengg0769 chengg0769 等级: 结帖率:100% #21 得分:0 回复于: 2010-06-13 23:14:40 看下c main函数的几种写法即知。 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 y275632943 y275632943 等级: 结帖率:0% #22 得分:0 回复于: 2012-06-06 09:27:07 谢谢了,帮我解决了大问题 对我有用[0] 丢个板砖[0] 引用 | 举报 | 编辑 删除 管理 --> --> --> --> --> --> 管理菜单 置顶 推荐 锁定 移动 编辑 删除 帖子加分 帖子高亮 结帖 发帖 回复 写出你眼中的IE11 赢取新年好礼! 勇敢写出你的爱 赢莫文蔚签名大礼 2014年4月微软MVP申请开始了! 陈勇- 敏捷开发现状及发展之路 CSDN高校俱乐部 高校全新改版邀你来学习和挑战 本帖子已过去太久远了,不再提供回复功能。 核心技术类目 全部主题 Java VPN Android iOS ERP IE10 Eclipse CRM JavaScript Ubuntu NFC WAP jQuery 数据库 BI HTML5 Spring Apache Hadoop .NET API HTML SDK IIS Fedora XML LBS Unity Splashtop UML components Windows Mobile Rails QEMU KDE Cassandra CloudStack FTC coremail OPhone CouchBase 云计算 iOS6 Rackspace [关闭] [关闭]