vb调用dll如何传递字符串指针

assummerflower 2019-05-28 04:17:43
在c++编写的dll头文件中,函数定义如下

int EXPORT_API usb_relay_device_open_with_serial_number(const char *serial_number,unsigned len);
/*open device that serial number is serial number*/
/*return:This funcation return a valid handle to the device on success or NULL on failure*/
/**eg:usb_relay_device_open_with_serial_number("abcde",5")*/



在vb中尝试以下几种方式编写程序(设备序列号为“QAAMZ”)
1、直接传递字符串
声明:
private declare function usb_relay_device_open_with_serial_number Lib“xx路径”(byval SerNum as string,byval lenth as long)as long
调用
dim return as long
return=usb_relay_device_open_with_serial_number(“QAAMZ”,5)
2、传递指针
声明中 byval SerNum as long
其中sernum为序列号数组首字符的指针地址

但都出现“DLL调用约定错误”的提示。

求教~

ps:这个问题的前置提问:https://bbs.csdn.net/topics/392563831
已经解决了利用dll获得设备序列号的问题。


...全文
467 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
assummerflower 2019-05-31
  • 打赏
  • 举报
回复
引用 18 楼 milaoshu1020的回复:
[quote=引用 17 楼 assummerflower 的回复:]
[quote=引用 15 楼 milaoshu1020的回复:][quote=引用 14 楼 assummerflower 的回复:]
[quote=引用 13 楼 脆皮大雪糕的回复:][quote=引用 10 楼 assummerflower 的回复:]
[quote=引用 8 楼 脆皮大雪糕的回复:]要被VB调用的函数都要用stdcall

我不知道我的是不是stdcall,也不知道在哪里改…求指导啊[/quote]

要看DLL的源代码,找到函数的声明,确认是否有声明 stdcall调用,如果没有则需要修改,修改以后要重新编译。[/quote]
哪个是源代码?用什么软件编译?我这有厂家给的.dll,.h和.lab[/quote]
厂家说没说是否支持VB6调用?
厂家试验过,能用VB6调用吗?
是否可以让厂家给你个VB6调用的例子?
[/quote]
商家转卖的一个小东西,联系不到厂家…[/quote]
实在不行的话,你可以用VC的ATL工程包装一下,然后用VB6调用;
因为有可能这个API函数VB6没法直接调用;
方便的话我可以给你包装一下,不过你得把.H和.DLL发给我;
你可以用百度网盘,上传并共享,把地址贴在这里;
也可以把这几个文件打包发送到我的邮箱:milaoshu1020@126.com;[/quote] 感谢感谢,已经发到邮箱了
脆皮大雪糕 2019-05-30
  • 打赏
  • 举报
回复
要被VB调用的函数都要用stdcall
milaoshu1020 2019-05-30
  • 打赏
  • 举报
回复
.cpp、.h 是源代码文件;
试试修改 .cpp、.h(再导出的函数名称前边加上_stdcall);
比如:
int _stdcall EXPORT_API usb_relay_device_open_with_serial_number(const char *serial_number,unsigned len);
.lib、.dll 是编译生成的文件,.dll是vb6实际用到的文件;

因为我没有测试过,仅仅是看别人这么说的,所以也不太确定这个方法能达到效果;
你可以试一试,不行再想其它的办法;
milaoshu1020 2019-05-30
  • 打赏
  • 举报
回复
引用 17 楼 assummerflower 的回复:
[quote=引用 15 楼 milaoshu1020的回复:][quote=引用 14 楼 assummerflower 的回复:]
[quote=引用 13 楼 脆皮大雪糕的回复:][quote=引用 10 楼 assummerflower 的回复:]
[quote=引用 8 楼 脆皮大雪糕的回复:]要被VB调用的函数都要用stdcall

我不知道我的是不是stdcall,也不知道在哪里改…求指导啊[/quote]

要看DLL的源代码,找到函数的声明,确认是否有声明 stdcall调用,如果没有则需要修改,修改以后要重新编译。[/quote]
哪个是源代码?用什么软件编译?我这有厂家给的.dll,.h和.lab[/quote]
厂家说没说是否支持VB6调用?
厂家试验过,能用VB6调用吗?
是否可以让厂家给你个VB6调用的例子?
[/quote]
商家转卖的一个小东西,联系不到厂家…[/quote]
实在不行的话,你可以用VC的ATL工程包装一下,然后用VB6调用;
因为有可能这个API函数VB6没法直接调用;
方便的话我可以给你包装一下,不过你得把.H和.DLL发给我;
你可以用百度网盘,上传并共享,把地址贴在这里;
也可以把这几个文件打包发送到我的邮箱:milaoshu1020@126.com;
assummerflower 2019-05-30
  • 打赏
  • 举报
回复
引用 15 楼 milaoshu1020的回复:
[quote=引用 14 楼 assummerflower 的回复:]
[quote=引用 13 楼 脆皮大雪糕的回复:][quote=引用 10 楼 assummerflower 的回复:]
[quote=引用 8 楼 脆皮大雪糕的回复:]要被VB调用的函数都要用stdcall

我不知道我的是不是stdcall,也不知道在哪里改…求指导啊[/quote]

要看DLL的源代码,找到函数的声明,确认是否有声明 stdcall调用,如果没有则需要修改,修改以后要重新编译。[/quote]
哪个是源代码?用什么软件编译?我这有厂家给的.dll,.h和.lab[/quote]
厂家说没说是否支持VB6调用?
厂家试验过,能用VB6调用吗?
是否可以让厂家给你个VB6调用的例子?
[/quote] 商家转卖的一个小东西,联系不到厂家…
assummerflower 2019-05-30
  • 打赏
  • 举报
回复
商家转卖的一个小东西,联系不到厂家…
assummerflower 2019-05-30
  • 打赏
  • 举报
回复
引用 5 楼 milaoshu1020的回复:
[quote=引用 4 楼 assummerflower 的回复:]
[quote=引用 3 楼 milaoshu1020的回复:]vc的dll中需要把调用模式设为_stdcall才能让vb调用
比如函数:
void add (int a ,int b)
就无法在VB中调用
要改为:
void add _stdcall (int a ,int b)

转自:
https://bbs.csdn.net/topics/350190581
第2楼;

我没看过dll里面的代码。不过之前有两个函数已经运行成了,是不是应该是stdcall的?[/quote]
引用成的函数声明是什么样子的?[/quote] 引用成了两个函数。 1,初始化函数 在dll头文件中声明为: int EXPORT_API usb_relay_init(void) /*init the usb relay library return 0 on success and-1 on failure*/ 在vb中声明为 private declare function usb_relay_init lib."路径"()as long 2,第二个函数是扫描设备信息的,在另一个帖子里大神您回复过我,按照您的方法解决了。 ps:如果要修改dll为stdcall方式,应该怎么修改,现在有.cpp、.h、.lib、.dll好几个文件,应该改哪个?
milaoshu1020 2019-05-30
  • 打赏
  • 举报
回复
引用 14 楼 assummerflower 的回复:
[quote=引用 13 楼 脆皮大雪糕的回复:][quote=引用 10 楼 assummerflower 的回复:]
[quote=引用 8 楼 脆皮大雪糕的回复:]要被VB调用的函数都要用stdcall

我不知道我的是不是stdcall,也不知道在哪里改…求指导啊[/quote]

要看DLL的源代码,找到函数的声明,确认是否有声明 stdcall调用,如果没有则需要修改,修改以后要重新编译。[/quote]
哪个是源代码?用什么软件编译?我这有厂家给的.dll,.h和.lab[/quote]
厂家说没说是否支持VB6调用?
厂家试验过,能用VB6调用吗?
是否可以让厂家给你个VB6调用的例子?
assummerflower 2019-05-30
  • 打赏
  • 举报
回复
引用 13 楼 脆皮大雪糕的回复:
[quote=引用 10 楼 assummerflower 的回复:] [quote=引用 8 楼 脆皮大雪糕的回复:]要被VB调用的函数都要用stdcall
我不知道我的是不是stdcall,也不知道在哪里改…求指导啊[/quote] 要看DLL的源代码,找到函数的声明,确认是否有声明 stdcall调用,如果没有则需要修改,修改以后要重新编译。[/quote] 哪个是源代码?用什么软件编译?我这有厂家给的.dll,.h和.lab
脆皮大雪糕 2019-05-30
  • 打赏
  • 举报
回复
引用 10 楼 assummerflower 的回复:
[quote=引用 8 楼 脆皮大雪糕的回复:]要被VB调用的函数都要用stdcall
我不知道我的是不是stdcall,也不知道在哪里改…求指导啊[/quote] 要看DLL的源代码,找到函数的声明,确认是否有声明 stdcall调用,如果没有则需要修改,修改以后要重新编译。
milaoshu1020 2019-05-30
  • 打赏
  • 举报
回复
引用 11 楼 assummerflower 的回复:
[quote=引用 7 楼 milaoshu1020的回复:].cpp、.h 是源代码文件;
试试修改 .cpp、.h(再导出的函数名称前边加上_stdcall);
比如:
int _stdcall EXPORT_API usb_relay_device_open_with_serial_number(const char *serial_number,unsigned len);
.lib、.dll 是编译生成的文件,.dll是vb6实际用到的文件;

因为我没有测试过,仅仅是看别人这么说的,所以也不太确定这个方法能达到效果;
你可以试一试,不行再想其它的办法;

没什么变化。
vb只用到了dll,dll没有改动,程序也就没有变化了。[/quote]
需要编译源代码为DLL;
就像VB6的生成EXE/DLL/OCX一样;
assummerflower 2019-05-30
  • 打赏
  • 举报
回复
引用 7 楼 milaoshu1020的回复:
.cpp、.h 是源代码文件;
试试修改 .cpp、.h(再导出的函数名称前边加上_stdcall);
比如:
int _stdcall EXPORT_API usb_relay_device_open_with_serial_number(const char *serial_number,unsigned len);
.lib、.dll 是编译生成的文件,.dll是vb6实际用到的文件;

因为我没有测试过,仅仅是看别人这么说的,所以也不太确定这个方法能达到效果;
你可以试一试,不行再想其它的办法;
没什么变化。 vb只用到了dll,dll没有改动,程序也就没有变化了。
assummerflower 2019-05-30
  • 打赏
  • 举报
回复
引用 8 楼 脆皮大雪糕的回复:
要被VB调用的函数都要用stdcall
我不知道我的是不是stdcall,也不知道在哪里改…求指导啊
脆皮大雪糕 2019-05-30
  • 打赏
  • 举报
回复
stdcall的调用约定意味着:参数从右向左压入堆栈,被调用函数自身修改堆栈 cdecl调用约定的参数压栈顺序是和stdcall是一样的,参数首先由有向左压入堆栈。所不同的是,被调用函数本身不清理堆栈,调用者负责清理堆栈。 VB的调用方式是不自行清理堆栈的,其实WINDOWS API函数基本上都是stdcall。 _cdecl是C和C++程序的缺省调用方式。 当我们遇到这样的函数如fprintf()它的参数是可变的,不定长的,被调用者事先无法知道参数的长度,事后的清除工作也无法正常的进行,因此,这种情况我们只能使用cdecl。
milaoshu1020 2019-05-29
  • 打赏
  • 举报
回复
引用 4 楼 assummerflower 的回复:
[quote=引用 3 楼 milaoshu1020的回复:]vc的dll中需要把调用模式设为_stdcall才能让vb调用
比如函数:
void add (int a ,int b)
就无法在VB中调用
要改为:
void add _stdcall (int a ,int b)

转自:
https://bbs.csdn.net/topics/350190581
第2楼;

我没看过dll里面的代码。不过之前有两个函数已经运行成了,是不是应该是stdcall的?[/quote]
引用成的函数声明是什么样子的?
assummerflower 2019-05-29
  • 打赏
  • 举报
回复
引用 3 楼 milaoshu1020的回复:
vc的dll中需要把调用模式设为_stdcall才能让vb调用
比如函数:
void add (int a ,int b)
就无法在VB中调用
要改为:
void add _stdcall (int a ,int b)

转自:
https://bbs.csdn.net/topics/350190581
第2楼;
我没看过dll里面的代码。不过之前有两个函数已经运行成了,是不是应该是stdcall的?
milaoshu1020 2019-05-29
  • 打赏
  • 举报
回复
vc的dll中需要把调用模式设为_stdcall才能让vb调用
比如函数:
void add (int a ,int b)
就无法在VB中调用
要改为:
void add _stdcall (int a ,int b)

转自:
https://bbs.csdn.net/topics/350190581
第2楼;
assummerflower 2019-05-29
  • 打赏
  • 举报
回复
引用 1 楼 脆皮大雪糕的回复:
改一下声明,C里面传入指针的参数,VB里面用byref传入,类型为any private declare function usb_relay_device_open_with_serial_number Lib“xx路径”(byref SerNum as any,byval lenth as long)as long 接下来,C的char 其实就是字节数组。把VB的string转换成字节数组 dim a() as byte a = strconv("1234abcd" ,vbfromunicode) 最后,把数组的第一个元素传递进去,其实DLL那边获得的就是这个数组在内存里的起始地址。也就是这个数组的指针。 dim return as long return=usb_relay_device_open_with_serial_number(a(0) ,ubound(a)+1)
大神,还是不行,还是报dll调用约定错误。这个方法我之前也试过了,会不会除了传递指针那里,其他地方有我没注意到的错误。
脆皮大雪糕 2019-05-28
  • 打赏
  • 举报
回复
改一下声明,C里面传入指针的参数,VB里面用byref传入,类型为any private declare function usb_relay_device_open_with_serial_number Lib“xx路径”(byref SerNum as any,byval lenth as long)as long 接下来,C的char 其实就是字节数组。把VB的string转换成字节数组 dim a() as byte a = strconv("1234abcd" ,vbfromunicode) 最后,把数组的第一个元素传递进去,其实DLL那边获得的就是这个数组在内存里的起始地址。也就是这个数组的指针。 dim return as long return=usb_relay_device_open_with_serial_number(a(0) ,ubound(a)+1)

1,488

社区成员

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

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