| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4178 人关注过本帖
标题:关于VFP编译DLL,前半部分给新人作示范,后面有问题要问高手。
只看楼主 加入收藏
厨师王德榜
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:199
帖 子:987
专家分:4946
注 册:2013-2-16
结帖率:100%
收藏
已结贴  问题点数:10 回复次数:7 
关于VFP编译DLL,前半部分给新人作示范,后面有问题要问高手。
我看不断有人问VFP编译DLL以及调用的问题,今天有空,就随手写了一个示例,这是背景。
结果后面发现我这个示例有问题,但我找不出问题在哪里,所以,就把过程写上来,让大家帮我参谋参谋。
1、缘起
想做一个类似VB中split()这样的函数,能方便的用指定的字符串分割另一个字符串,并把结果放在一个数组里。
我用VFP9,由于有一个现成的函数,我就在示例里用了Alines()。你别问我说“既然有了Alines(),再编译这个DLL是不是有点多余了?”
我的回答是,我本来只是想用这个来给大家做一个示例而已,当然我也可以用别的问题来做示例,只是我的这个示例,在后来发现了我自己解释不了的问题,这是我帖子最后要问的,大家先耐心看,毕竟帖子的前半部分,对新手“VFP如何编译DLL”这样的问题,是有借鉴意义的。
2、我先写了一个PRG,代码是这样的:
程序代码:
*!* splitstr2array(cStr,strCut,Arrname) 作用:把字符串以特定字符分割后,存入数组。
*!* 参数说明:待分割的完整字符,分割的字符,准备装入的数组。
*!* 返回:数组的个数。
*!* 调用方式:1、先定义一个数组 DIMENSION arrB[1] (可能需要事先SET PROCEDURE TO ...)
*!* 2、一定要用传址方式,把数组作为参数传入Function ,例如 ;
*!* if splitstr2array("emp\loy\ee.n\ote\s\ ", "\",@arrB) >0 then 
*!*    =MESSAGEBOX('字符分割成功。',0,'提示:')
*!*    ELSE 
*!*    =MESSAGEBOX('字符分割失败。',0,'提示:')
*!*    ENDIF 
FUNCTION  splitstr2array  
LPARAMETERS cStr ,strCut ,Arrname 
    RETURN ALINES(Arrname, cStr, strCut)
ENDFUNC  

然后,我实际试用了一下:
程序代码:
DIMENSION arrB[1]
?splitstr2array("犍为,乐山,金口河,五通桥,小重庆,峨边,夹江", ",",@arrB)  &&  注意,待分割字符串中间是全角的逗号","
* 程序返回7 ,再测试一下数组:
?ALEN(arrb)  && 返回 7 
?arrb[5] && 返回 “小重庆” 
?arrb[7] && 返回 “夹江” 

看来,我的PRG是没有问题了,下面,来为大家示例一下怎么编译成一个DLL?
新建一个空白的项目,我取名为MyVfpDLL,项目中,在代码处,点新建,建立一个名为 mysess1splitstr 的PRG,内容和刚才那个PRG一样,
但是,首句和末句,要用Define ... EndDefine来包裹,具体是这样:
DEFINE CLASS mySess1 AS Session OLEPUBLIC
...粘贴刚才的PRG程序全文...
endDEFINE 

然后,保存PRG,点项目旁边的“连编”,先连编一下项目,看看有没有错误,没有错误,就再次连编,这次选择“单线程COM服务程序”,给目标文件取名为“myvfpdll.DLL”,这样VFP编译DLL的示例就讲完了,本帖的上半部分,作为给新手的示例,也就讲完了。
下面是在这个过程中,困扰我的问题:
连编DLL结束后,我试用了一下,在试用过程中,发现了问题,过程是这样的:
程序代码:
*先建立一个对象
ox=CREATEOBJECT("myvfpdll.mysess1")
*然后定义一个数组,为了和刚才区分,数组新取一个名字。
DIMENSION arrC[1]
?ox.splitstr2array("犍为,乐山,金口河,五通桥,小重庆,峨边,夹江", ",",@arrC)

运行后,返回7,返回的结果正确,但是,再测试这个数组的时候……
?ALEN(arrc)  && 返回的是1,不是我预想的7
?arrc[1]  && 返回的是.f. ???连一个字符都没返回?
我当时就困惑了?为啥在PRG中可能正常返回的,编译成DLL后,就不能了呢,而且从他能返回7来看,DLL内部拆分字符串的过程,应该是正常的,不正常的,只是把数组返回的这一步。

下面说说我后面做了哪些尝试:
1、把DLL中的PRG,Function 改成 PROCEDURE ,编译同样能通过,但结果是:如果是PRG中直接用,都能正确返回数组,如果是在DLL中用,都不能返回。
2、把arrc定义为全局变量,再传进DLL里,仍不能正常返回。
3、把ARRC直接定义为Arrc[7],即事先定义好数组的长度,仍不能正常返回。
当然,以上过程,DLL的返回值都是正常的7,只是数组无法正常返回。
以上就是困扰我的问题,百思而不得解,期待高手给我释疑解惑,谢谢。

[此贴子已经被作者于2016-6-10 17:18编辑过]

搜索更多相关主题的帖子: 字符串 
2016-06-10 17:07
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10538
专家分:42927
注 册:2014-5-20
收藏
得分:10 
假设:
arrC[1] = "ABC";
?ox.splitstr2array("犍为,乐山,金口河,五通桥,小重庆,峨边,夹江", ",",@arrC)
在splitstr2array里查看一下arrC[1],到底是什么?是不是"ABC",或者根本就不存在。
VFP的DLL有点特别,你甚至可以试试:
USE xxx ......
在splitstr2array里USE ...... CLOSE DATABASES ALL
调用splitstr2array后返回后再看看之前打开的表状态。
2016-06-10 20:29
厨师王德榜
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:199
帖 子:987
专家分:4946
注 册:2013-2-16
收藏
得分:0 
为了大家方便,我把源代码也用附件发上来,人多力量大,各位高手来帮我看看。
myvfpdll源码.zip (13.84 KB)
2016-06-11 08:16
厨师王德榜
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:199
帖 子:987
专家分:4946
注 册:2013-2-16
收藏
得分:0 
目前没有满意的答案,请容我延迟结贴。
等待高手出现。
2016-06-13 09:51
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10538
专家分:42927
注 册:2014-5-20
收藏
得分:0 
VFP的DLL是一个COM服务,可能有自己独立的线程空间,不能与主线程共享内存变量空间。
试试在主线程分配内存空间,将此内存空间地址作为DLL函数的IN/OUT参数,这样肯定可以。
2016-06-13 11:53
厨师王德榜
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:199
帖 子:987
专家分:4946
注 册:2013-2-16
收藏
得分:0 
我发现只有需要DLL返回数组的时候,会有这种情况,其它返回文本、返回数值的自定义DLL,都不会出现问题。楼上说的In/Out参数,这个我不知道怎么操作,有示例吗?谢谢。
2016-06-14 13:40
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10538
专家分:42927
注 册:2014-5-20
收藏
得分:0 
以下是引用厨师王德榜在2016-6-14 13:40:08的发言:

我发现只有需要DLL返回数组的时候,会有这种情况,其它返回文本、返回数值的自定义DLL,都不会出现问题。楼上说的In/Out参数,这个我不知道怎么操作,有示例吗?谢谢。

你那个数组就是VFP的In/Out参数,不算是函数返回值。
VFP的In/Out参数名前用@表示,自己分配的内存地址可直接作为In/Out参数。
2016-06-14 15:36
slm75
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2006-7-5
收藏
得分:0 
vfp dll参数返回值是有大小限制的。
2016-06-16 19:36
快速回复:关于VFP编译DLL,前半部分给新人作示范,后面有问题要问高手。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016798 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved