| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2223 人关注过本帖
标题:VFP调用外部函数问题
只看楼主 加入收藏
jxwcy
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2013-5-16
收藏
得分:0 
我的代码没什么要求,只要能通过调用GetPersonMsgA取得结构中各变更的内容就行。
2013-05-17 13:03
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
前面已经告诉你答案了,就这样。

授人以渔,不授人以鱼。
2013-05-17 13:04
jxwcy
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2013-5-16
收藏
得分:0 
正在学习
2013-05-17 13:08
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
获取的一块内存数据是连续的,只要按照设计的字段长度提取即可,注意偏移量和长度,那本质上就是数据表的字段读取模式。C字符串是以字符'\0'结束的,取字段数据时扫描这个字符,到它为止,后面的不要,那是垃圾数据,要就错了。每个字段从结构体每个字段的偏移量开始,按照结构声明的长度来算——不管是不是字符串字段,按照数据类型的真实尺寸求偏移量。

授人以渔,不授人以鱼。
2013-05-17 13:19
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
举个例子,你的结构体
char name[32];
char sex[4];
char nation[20];
这里是3个字段,前32个字符是name的,接着的4个字符是sex的,然后20个字符是nation的。由于C程序处理字符串以'\0'为结束,因此如果真实的name字符串没有19个字符长,那么它写入的'\0'字符不一定在第32个字符处,所以你不能依赖对方会替你填充空格(VFP语言的专用读数函数就会这样)或'\0',最稳妥的办法是从第1个字符开始依次扫描,找到'\0'就结束,这样得到的字符串就是name了;然后直接跳到第33个字符开始再扫描sex,如此下去……这样处理是包没错的,但你也可以测试是否可以不用检测'\0',以自己的测试结果为准,不保证有没有移植性问题,只要知道原理发生问题也可以自己处理了。

字符'\0'就是CHR(0)。

[ 本帖最后由 TonyDeng 于 2013-5-17 13:28 编辑 ]

授人以渔,不授人以鱼。
2013-05-17 13:26
jxwcy
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2013-5-16
收藏
得分:0 
我曾试过用一个长度足够的string变量作为参数,但只能取到一个name的值,用substr()也读不到这个变更name后面的内容,是不是以string变更做参数,只能被赋予第一个name的内容,后面传递不回来啊?
2013-05-17 13:37
taohua300
Rank: 12Rank: 12Rank: 12
来 自:光
等 级:贵宾
威 望:14
帖 子:1636
专家分:3906
注 册:2009-3-11
收藏
得分:0 
以下是引用TonyDeng在2013-5-17 12:41:33的发言:

 
CLEAR ALL
CLEAR
DECLARE GetSystemInfo IN WIN32API String @
cBuffer = SPACE(40)
GetSystemInfo(@cBuffer)
SystemInfo = CREATEOBJECT("_SystemInfo", @cBuffer)
? "处理器类型: " + TRANSFORM(SystemInfo.ProcessorType)
? "处理器个数: " + TRANSFORM(SystemInfo.NumberOfProcessors)
? "处理器架构: " + SystemInfo.ProcessorArchitecture
? "内存页大小: " + TRANSFORM(SystemInfo.PageSize)
? "可用内存起始地址: " + TRANSFORM(SystemInfo.MinimumApplicationAddress)
? "可用内存结束地址: " + TRANSFORM(SystemInfo.MaximumApplicationAddress)
RETURN  
 
DEFINE CLASS _SystemInfo AS Custom
 
    OemID = SPACE(4)
    ProcessorArchitecture = ""
    PageSize = 0
    MinimumApplicationAddress = 0
    MaximumApplicationAddress = 0
    ActiveProcessorMask = SPACE(4)
    NumberOfProcessors = 0
    ProcessorType = 0
    AllocationGranularity = SPACE(4)
    ProcessorLevel = SPACE(2)
    ProcessorRevision = SPACE(2)
   
    PROCEDURE Init(tcString)
        WITH This
            .NumberOfProcessors = CTOBIN(SUBSTR(tcString, 21, 4), "4RS")
            .ProcessorType = CTOBIN(SUBSTR(tcString, 25, 4), "4RS")
            LOCAL lnTemp
            lnTemp = CTOBIN(SUBSTR(tcString, 7, 2), "2RS")
            DO CASE
                CASE lnTemp == 0
                    .ProcessorArchitecture = "INTEL"
                CASE lnTemp == 6
                    .ProcessorArchitecture == "IA64"
                CASE lnTemp == 9
                    .ProcessorArchitecture = "AMD64"
                otherwise
                    .ProcessorArchitecture = "UNKNOWN"   
            ENDCASE
            .PageSize = CTOBIN(SUBSTR(tcString, 9, 4), "4RS")
            .MinimumApplicationAddress = CTOBIN(SUBSTR(tcString, 13, 4), "4RS")
            .MaximumApplicationAddress = CTOBIN(SUBSTR(tcString, 17, 4), "4RS")
        ENDWITH
    ENDPROC
   
ENDDEFINE
这样啊
我以为是类似c那样直接构造一个类作为参数传给函数

个性太多,无法显示
2013-05-17 13:38
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
我不知道你对C是否熟悉,但不妨补充一下相关的东西:C的字符串以'\0'为结束标志,所以定义char name[20]的字符数组实际上只能存储19个字符,要给字符'\0'留1个位置,亦即name顶多只有19个字符,实际长度是可变的,就靠找到'\0'来定,C程序是不管'\0'原先储存了什么数据的,你如果直接读入20个字符,当实际没有那么长的时候,就等于把后面随机的数据也读了进来(须知C是习惯于把方便留给自己麻烦留给别人的程序员发明的语言,它只管自己高效不管别人易用与否);其次,C的数组计数是从0开始,而VFP是从1开始,注意区别。

授人以渔,不授人以鱼。
2013-05-17 13:41
taohua300
Rank: 12Rank: 12Rank: 12
来 自:光
等 级:贵宾
威 望:14
帖 子:1636
专家分:3906
注 册:2009-3-11
收藏
得分:0 
以下是引用jxwcy在2013-5-17 13:37:07的发言:

我曾试过用一个长度足够的string变量作为参数,但只能取到一个name的值,用substr()也读不到这个变更name后面的内容,是不是以string变更做参数,只能被赋予第一个name的内容,后面传递不回来啊?
看看大T版的那段代码
然后结合在25楼说的那些
尝试一下看看能取出正确值不

另外,不是说你的string足够长就可以
有些时候,string的长度不准确,在执行的时候函数会报错的

个性太多,无法显示
2013-05-17 13:42
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
无法直接传递类的,因为那个函数参数要求内存块的指针地址,而VFP不提供底层指针函数,只能自己先分配出40个字节的内存空间给C函数写入数据,然后自己再从这块内存中提取出需要的东西——这本质上与文件读写一样,只不过存储介质是内存而不是外部磁盘罢了。当不熟悉与其他语言交互的时候,完全可以用读写文件的方法来交换数据,不必动用DLL接口的,操作系统有足够的缓存机制来加速,未必比直接交换慢多少,当然这要自己权衡了。

授人以渔,不授人以鱼。
2013-05-17 13:47
快速回复:VFP调用外部函数问题
数据加载中...
 
   



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

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