急!!!PB调用DLL传结构体参数出错,请各位大虾多多指教

zhangyuanlovelife 2008-01-17 10:17:28
各位大虾大家好。我现在有这样一个问题,希望各位高手能赐教。
我有一个用VC写的DLL,里面有一个接口函数是:
DWORD _stdcall HSFormat
(
IN HANDLE hCard,
IN HS_FORMATINFO hsFormatInfo
);
里面有一个结构体参数定义如下:
typedef struct _HS_FORMATINFO
{
LPCSTR szLabel;
LPCSTR szSOPin;
DWORD dwSOPinRetry;
LPCSTR szUserPin;
DWORD dwUserPinRetry;
DWORD dwReserved;
}HS_FORMATINFO, *PHS_FORMATINFO;
我用PB9来调用这个接口,我在PB9中所做的声名如下:
function ulong HSFormat(ulong hCard,hs_formatinfo formatinfo) library "xxx.dll",在PB9中的对应结构体如下:
hs_formatinfo其中对应的各个参数如下:
string strlabel
string strSOPin
unsignedlong ulSOPinRetry
string strUserPin
unsignedlong ulUserPinRetry
unsignedlong ulReserved
可是在PB中调用到HSFormat时就报如下的错误:


---------------------------
PowerBuilder Application Execution Error (R0042)
---------------------------
Application terminated.

Error: Specified argument type differs from required argument type at runtime in DLL function hsformat.
(invalid stack pointer on return from function call) at line 37 in clicked event of object cb_hk_format of w_examplecode_main.
---------------------------
确定
---------------------------

我看应该还是DLL中的结构体和PB中的结构体类型不匹配,可是查遍了资料,感觉现在的PB中的结构体声明应该是正确的啊,请各位大虾帮帮忙忙,看是什么原因引起的。
另外我发现PB中掉DLL,如果参数是结构体的时候,经常出问题,不知道是什么原因?
急!!!!!!!!!!!!!谢谢各位大虾。
...全文
1214 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
AFIC 2008-01-18
  • 打赏
  • 举报
回复
至于你说的

难道PB调用第三方的DLL库中的函数需要传结构体作为函数参数的时候,只能传结构体指针么

显然是不会的,只是你遇到了特殊情况,又不好定位原因在哪里而已。
AFIC 2008-01-18
  • 打赏
  • 举报
回复
>>如何结帖子给分呢???


看这个
http://topic.csdn.net/u/20080110/19/7cb462f1-cac6-4c28-848e-0a879f4fd642.html
AFIC 2008-01-17
  • 打赏
  • 举报
回复
用LPSTR吧
青锋-SS 2008-01-17
  • 打赏
  • 举报
回复
改成下面试试:
ref string strlabel
ref string strSOPin
unsignedlong ulSOPinRetry
ref string strUserPin
unsignedlong ulUserPinRetry
unsignedlong ulReserved
zhangyuanlovelife 2008-01-17
  • 打赏
  • 举报
回复
To AFIC:
十分感谢你的参与。

我又重试了一下是可以的。也就是把传结构体参数的DLL,我又封装了一层,改成传结构体指针,然后PB中用REF声明,可以正确调用了。但是还有一个问题就是:

难道PB调用第三方的DLL库中的函数需要传结构体作为函数参数的时候,只能传结构体指针么????????????????????为什么???

还有,就是如何结帖子给分呢???


^-^谢谢大家!!!!!
zhangyuanlovelife 2008-01-17
  • 打赏
  • 举报
回复
To AFIC:
谢谢你。
可能直接写一个DLL这种方法可以,但是我调的底层库,要操作硬件的,不知道底层库是怎么处理传进去的结构体的。我刚才就是又封装了一层,自己声明了一个结构体,传指针进去,但是调试不通过。没有办法了。

真的十分感谢您的参与,还要麻烦您帮着再想想,看可能是哪里的问题。
谢谢!!!!!!!!!!!!!!!!!!!!!!!!!!!!
zhangyuanlovelife 2008-01-17
  • 打赏
  • 举报
回复
To 31737951

声明如下:也就是引用
function ulong HSFormat(ulong hCard,ref hs_formatinfo formatinfo) library "xxx.dll"

PB中如下调用:
hs_formatinfo formatinfo
formatinfo.sLabel="TestOnly"
formatinfo.ssopin="1111"
formatinfo.ulsopinretry=15
formatinfo.suserpin="1111"
formatinfo.uluserpinretry=15
lngRet=HSFormat(hCard,formatinfo)

还是出一开始的那个错误,说什么类型不匹配的意思。
我感觉问题的重点应该在DLL中的函数传递的是结构体参数,而非结构体指针,所以PB中调用的时候出问题了。因为如果排除类型转换的错误的话,我调过一个传递结构体指针的,PB声明REF就可以正确执行,而现在的DLL中传递的是结构体而非其指针,就出问题了。所以我感觉现在的问题在于:
1。我的DLL中的结构体和PB中的结构体类型是否真的对应没有错误(至少我查了这么多资料和以前调用DLL的经验,应该是类型转换没有错误了)
2。PB中调用DLL函数,如果要传递结构体作为参数的话,是否要求DLL中的函数参数必须是结构体指针,也就是PB中要声明为REF?如果不是的话,那传递结构体和传递结构体指针都对的话是什么样的呢?

请各位大虾多多指教!
这个问题都解决了两天了,各位大虾救救小弟!!!!!!!!!!!!不胜感激,谢谢大家!!!!!!!!!!
AFIC 2008-01-17
  • 打赏
  • 举报
回复
可以解决阿,你的dll中建一个结构叫a,
你的dll传得假如叫b
b.xxx = *a.xxx
b.xx = *a.xx
用b当参数掉那个dll,都是大意,c早忘光了……
zhangyuanlovelife 2008-01-17
  • 打赏
  • 举报
回复
To AFIC :
你的意思是自己再写一个DLL,把那个直接传结构体的封装成传结构体指针的,然后PB中用ref来调用?这样可行么?
因为虽然我可以再封一层写成传结构体指针的,但是,传到底层,还是传的结构体啊?而不是结构体指针。谢谢你。我先试一下这种方法吧。

十分感激!!!!!!!!!我先看能不能解决问题。

这种方法不能解决问题,因为虽然我封一层,但是底层DLL还是传的结构体而不是结构体的指针,所以,根本执行不过去的。我刚试了。
还要想别的办法了。
31737951 2008-01-17
  • 打赏
  • 举报
回复
声明的时候加 ref
function ulong HSFormat(ulong hCard,ref hs_formatinfo formatinfo) library "xxx.dll"

=======================
另外调用的时候 LPCSTR 表示指针引用 并不晓得 数据的长度
你使用的时候 需要初始化 结构体



zhangyuanlovelife 2008-01-17
  • 打赏
  • 举报
回复
To AFIC :
你的意思是自己再写一个DLL,把那个直接传结构体的封装成传结构体指针的,然后PB中用ref来调用?这样可行么?
因为虽然我可以再封一层写成传结构体指针的,但是,传到底层,还是传的结构体啊?而不是结构体指针。谢谢你。我先试一下这种方法吧。

十分感激!!!!!!!!!我先看能不能解决问题。
AFIC 2008-01-17
  • 打赏
  • 举报
回复
hs_formatinfo formatinfo
PB重新拷贝一份,然后传给DLL
ref hk_fileinfo fileInfo
PB直接把对象的引用传给DLL

现在也看不到你的DLL啥的,光看你的描述似乎没有问题
既然你调用ref hk_fileinfo fileInfo是成功的
你可以自己做一个DLL成上边的格式,也就是一个壳,
继而调用HSFormat,虽然很麻烦,但起码比不能用好些。
zhangyuanlovelife 2008-01-17
  • 打赏
  • 举报
回复
To AFIC :

谢谢你的参与。我用的是PB9.0。我现在纳闷的是,我上面出问题的DLL中的结构体和PB中声明的结构体类型有不匹配的么?我看是没有了,应该类型是相互匹配的了。可是既然DLL中的结构体和PB中的结构体类型是匹配的了。DLL函数要求传一个结构体,那我在PB中传一个结构体不就行了么?为什么就是不对呢?

另外,PB9的传结构体:
function ulong HSFormat(ulong hCard,hs_formatinfo formatinfo) library "xxx.dll",
和传结构体的引用:
function ulong HK_CreateFile(ulong hCard,ref hk_fileinfo fileInfo) library "YYY.dll"
有什么区别呢?为什么我的一个库中,函数本身是传结构体指针,我就在PB中传一个ref hk_fileinfo fileInfo也就是结构体引用就成功呢?


谢谢!!!!!!!!!!!!
这个问题已经捆饶了我很长时间了。昨天查了一天也没查出来,还请您多多指教,谢谢。
AFIC 2008-01-17
  • 打赏
  • 举报
回复
REF决定pb调用的时候是复制一份,还是直接把指针仍过去
现在的可能是你用了pb10以上的版本,如果不是我再想想。
zhangyuanlovelife 2008-01-17
  • 打赏
  • 举报
回复
To AFIC :

DLL中的类型我是不能修改的,也就是,就是LPCSTR ,我不能修改成LPSTR。另外我看PB9帮助中如下:
Characters and strings

Datatype in source code Size, sign, precision PowerBuilder datatype
char 8 bits, signed Char
string 32-bit pointer to a null-terminated array of bytes of variable length String
The Windows 32-bit FAR pointer LPSTR is declared in PowerBuilder as string.
Reference arguments When you pass a string to an external function by reference, all memory management is done in PowerBuilder. The string variable must be long enough to hold the returned value. To ensure that this is true, first declare the string variable, and then use the Space function to fill the variable with blanks equal to the maximum number of characters that you expect the function to return.
也就是LPSTR,确实应该转换成PB9中的string类型。而我查资料中如下:

哟!没注意到有 Const 关键字;这样的话是应该从 pb 向 dll 传数据了,那么根本就不要用 REF,直接 string 就好了!pb 不支持在外部函数声明中使用常量关键字,因为没有必要;

所以,LPCSTR 类型也应该转换成PB9中的string类型,也是正确的。
现在我查了很多资料是,类型转换应该没什么问题,可是,为什么,把这个结构体传到DLL时就报错误呢?请各位大虾给分析一下。



另外,我调用一个别的库,如果传递的是一个结构体指针,是没有问题的,也就是如下:
DLL中如下:
DWORD _stdcall HK_CreateFile
(
IN HANDLE hCard,
IN PHK_FILEINFO pFileInfo
);
PHK_FILEINFO pFileInfo这个是一个结构体指针,PB中声明如下:
function ulong HK_CreateFile(ulong hCard,ref hk_fileinfo fileInfo) library "YYY.dll"
结构体,PB中:ref hk_fileinfo fileInfo,这样就是正确的,不知道是什么原因???????????????????????????????
zhangyuanlovelife 2008-01-17
  • 打赏
  • 举报
回复
To sdhylj :
PB结构体中,是没有ref string这种类型吧,我倒是这样试了:
function ulong HSFormat(ulong hCard,ref hs_formatinfo formatinfo) library "xxx.dll",

但是也不对的,再说了,现在是从PB传结构体到DLL,应该不用REF的。想破头皮都想不出是什么原因。
难道PB调用DLL中函数,如果参数传递是结构体的时候,有什么需要注意的么?请各位大虾多多指教。

604

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 控件与界面
社区管理员
  • 控件与界面社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧