最近调一个医保接口,就一个声明和调用的问题上卡了一个星期没有解决,和接口商只要到了一个dephi的声明,而我用的是VB,怎么整都不行,请大家帮帮我吧,我已经发一个帖子[Dephi声明如何转VB声明],不少朋友给了我热心的帮助,但是天不帮我,还没调通.现在我把整个调试环境发给大家,哪位不忙不妨调调
匿名提取文件连接 http://pickup.mofile.com/7587685010050640
或登录Mofile,使用提取码 7587685010050640 提取文件 我在此致以最最崇高的感谢!!!
解决方案 »
- vb中浮点数转换问题。急呀,谢谢
- 关于MSHFLEXGRID
- 用什么函数得到鼠标中间的轮子转动事件
- 关于文本输入的问题
- 请问各位有没有办法设置LABEL显示时的字间距.就像WORD一样可改变的.
- 请教了,如何用VB合并多个DOC成一个文件
- win2000下 textbox 锁定后还能编辑,请问怎么回事?如何解决
- 能否共同讨论一下关于打开dicom3.0格式文件的问题,我只有十分了,大家以学习为主,好吗?
- 为什么MSHFlexGrid1控件绑定的数据不与ADODC1的数据同步?
- @_@ 在VB中,如何实现将一指定HTML文件作为一邮件的正文发送出去!高手请进!!!@_@
- vb动态加入ShockwaveFlash后怎么用ShockwaveFlash1_FSCommand?
- 请教VB程序中写入密码防止被盗的方法
,点击[下载文件(IE浏览器)],不能下载可能是你的IE或防火墙阻止了吧
或者打开http://file.mofile.com,输入提取码7587685010050640,然后[提取文件]
(ByVal lpstrOperID As Long, ByVal lpstrReturnMessage As Long) As LongSub test()
Dim strOperId As String
Dim strMsg As String
'字符串初始化'
strOperId = "{F9AEE43D-E6B6-4787-84CC-FCB92F05A9DC}"
strMsg = String$(200, 0)
'完成其他调用该函数之前需要的初始化工作:’
'比如你在16楼说的生成表和修改配置'
'根据zdtlmti.dll具体情况,以下两种写法选择一种:'
'(1)如果zdtlmti这个库接受的是UNICODE字符串, 用以下代码'
checkuser StrPtr(strOperId), StrPtr(strMsg)
MsgBox strMsg
'(2)如果zdtlmti这个库接受的是ANSI字符串,用以下代码'
strOperId = StrConv(strOperId, vbFromUnicode)
strMsg = StrConv(strMsg, vbFromUnicode)
checkuser StrPtr(strOperId), StrPtr(strMsg)
MsgBox strMsg
strMsg = StrConv(strMsg, vbUnicode)
End Sub
http://zbl5174.download.csdn.net/
在网上找了一些有关DEPHI 的var参数的一些区别,以上各位并没有注意到这个var,也许以为变量,就是变量吧。
这个var加上参数的时候,DEPHI会做一些特殊的处理:自动转变这一参数为一个地址
按照我的理解,这个声明如果转化成VB语言的话,应该是
function checkuser(Byval OperID As String,
Byref returnMessage As String) as Integer
你最好不要声明为String,因为VB会对动态库调用的字符串参数自动做Unicode到ANSI的转换,可能会导致你的结果不正确。你先弄清楚你的动态库的字符串是Unicode编码还是ANSI编码。另外,7楼的代码你看了并且试了么?
试试这个
Option ExplicitPublic Declare Function checkuser Lib "zdtlmti.dll" _
(ByVal OperID As String, ByRef pReturnMessage As Long) As LongSub test()
Dim strOperId As String
Dim strMsg As String
Dim a() As Byte
Dim ptr As Long
Dim i As Long
strOperId = "{F9AEE43D-E6B6-4787-84CC-FCB92F05A9DC}"
ReDim a(0 To 200)
ptr = VarPtr(a(0))
Debug.Print Hex(ptr)
checkuser strOperId, ptr
Debug.Print Hex(ptr) '确认一下指针是否不变'
i = InStrB(1, a, ChrB(0))
If i = 0 Then i = 201
strMsg = StrConv(LeftB(a, i - 1), vbUnicode)
MsgBox strMsg
End Sub
如果 C 都不能调用成功,就是 dll 本身的问题了。
就在r=checkuser StrPtr(strOperId), StrPtr(strMsg这一行挂的
7楼有两个checkuser StrPtr(strOperId), StrPtr(strMsg)你在哪个挂的?
他分析说dll本身不应该有什么问题,这是VB的不足,傻瓜实用,但是很多细的地方微软处理得不够精明;
他建议先通过其它调试手段调着,没必要在这个问题上叫针儿,除非非得单步调试,他说可以用C类语言再写个
Dll,把这个dephi写的Dll包起来,我听了好像就是VB-调用-C写的dll-再调用-dephi写的dephi,多绕一道湾.反正他以前就这么干过.
与他一席话,胜过十年功,又觉得自己太渺小了.
哈,这种套路心领神会还行,不一般人能干出来的.
声明时如果参数为long,传入是就得是StrPtr(s);
声明时如果参数为string,直接传入s就行,
r=checkuser(strOperId, ptr)
Dim strMsg As String
Dim a() As Byte
以上是几个前辈的方案。我不赞同这些变量都定义成动态系类型。VB的动态系类型在内存中排列是很特殊的。我个人建议使用以下思路:
dim strOperId(255) as byte 定义256字节空间
dim strMsg(1023) as byte 定义1024字节空间
这样定义,才是顺序排列数据,REDIM()、String()返回的都不是顺序排列的空间段,VB的动态系类型是VB的独有特性。发地址给DLL,DLL按照C惯例根本收不到顺序排列的数据,VB的动态系类型都包含描述符,只有VB自己读的出来,DLL那边收到的可能是类型描述符而不是真实数据的首地址,只有静态数组才是连续内存序列,不掺杂别的东西。
推荐使用ASC函数,利用循环,把 "{F9AEE43D-E6B6-4787-84CC-FCB92F05A9DC}"这段字符装载到strOperId中,而不要使用能返回动态字符串或者动态数组的字符串处理函数。
strOperId(0)=ASCB("{")
strOperId(1)=ASCB("F")......依此类推,用循环法自动取字符,遇到中文,还要分别装载高8位和低8位。
最后按照C语言惯例,要在字符串结尾加上0,strOperId(结尾ID)=0。
C惯例中,在处理到0时,才结束。如果没有0,C系中的字符串处理程序指针会飞出数据段,后果不堪设想。我之所以频繁提到C惯例,是因为大多数程序是按照C惯例写的,甚至包括Dephi也是趋向C语言,而VB在处理字符串时,是个特例,VB甚至不理睬0的存在,它另有办法判断字符串长度。我支持以下VB声名方式,尤其是strOperId的类型,至于lpstrReturnMessage,前面先辈提醒可能是char**,我表示赞同,不过懒得进一步确认。至少lpstrOperID声明是对的。
Public Declare Function checkuser Lib "zdtlmti.dll" _
(ByVal lpstrOperID As Long, ByVal lpstrReturnMessage As Long) As Long以下是调用方法:传送了strOperId的首地址32位Long指针,指针所指向的空间遵循C惯例排列了全部信息,单位是8字节BYTE。至于strMsg,扔有待推敲。
....=checkuser( strOperId(0),strMsg(0))
[5.修改了ClientConfig.ini中的[DB]下的配置,使其故意不对,然后运行编译后的[Dll测试.exe],错误和3一样,是不是说明在VB调试环境下Dll没有读取到ClientConfig.ini的内容?],
其实真就是VB调试环境下Dll没有读取到ClientConfig.ini的内容,就是因为一调试就崩溃,没有任何有用的提示,所以一直没想到;
根本没有大家说的指什之类的问题,怎么测试都好使,17楼的方法试了也好使:
1.声明时参数为string,直接传入str即可,
2.声明时能数为long,传入StrPtr(str)也行
我相信大家遇到的VB调试dll时崩溃的问题,如果dll本身需要初始化,大多是这个dll找不到外部文件导致.
特别感谢这些天各楼层弟兄的顶力帮助,祝大家国庆快乐!