关于DLL文件的引用问题

shanyonggang 2012-11-08 11:26:46
我有1个DLL文件:RationalScaleScale.dll中有库函数如下:
USHORT GetInfo(char *Manufacturer,char *Producer,char *SerialNumber,char *BufLength);
功能:读取找到的设备信息
参数:char *Manufacturer 厂商字符串,一般为: Rational
char *Producer 产品字符串,一般为: USB303
char *SerialNumber 产品序列号,一般为:XXXX-XXXX 即 “硬件版本号”-“软件版本号”
char *BufLength 设备缓冲区长度。
-------------------------------------

我不知道在VB中:如何声明?如何引用?如何获取产品序列号?希望各位朋友帮助!!谢谢请给出代码!!
------------------------------------------------------
...全文
301 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
shanyonggang 2012-11-16
  • 打赏
  • 举报
回复
5楼的方法,我用了但仍是产生DLL调用约定错误! -------------------------------------------------- of123你好! 你写的那个类,不知怎么用,希望你给我完整用法!
shanyonggang 2012-11-16
  • 打赏
  • 举报
回复
用方法2 2 如果没有改 DLL 源码的条件,可以再写一个 DLL 作中转,这个 DLL 的函数声明为 __stdcall 约定,它来调用原函数。 ------------------------------ 我任为比较好,但是不知怎么写?应该可以用vc6.0完成吗,而且应是com组件吗?谢谢回复!!!
几罗星人 2012-11-16
  • 打赏
  • 举报
回复
引用 9 楼 of123 的回复:
这个类不是我写的,是微软提供的范例。我并没有测试过。我一般会在 DLL 直接采用 __stdcall 关键字。 你可以仿照它试试。 Imports System Imports Microsoft.VisualBasic Imports System.Runtime.InteropServices '声明一个叫做 LibWrap 的类 Public Class LibWra……
他这个类是VB.net的,如果你是VB6的就要转一下
of123 2012-11-16
  • 打赏
  • 举报
回复
这个类不是我写的,是微软提供的范例。我并没有测试过。我一般会在 DLL 直接采用 __stdcall 关键字。 你可以仿照它试试。 Imports System Imports Microsoft.VisualBasic Imports System.Runtime.InteropServices '声明一个叫做 LibWrap 的类 Public Class LibWrap ' Visual Basic does not support varargs, so all arguments must be ' explicitly defined. CallingConvention.Cdecl must be used since the stack ' is cleaned up by the caller. ' USHORT GetInfo(char *Manufacturer,char *Producer,char *SerialNumber,char *BufLength); <DllImport("RationalScaleScale.dll", CallingConvention := CallingConvention.Cdecl)> _ Overloads Shared Function GetInfo ( _ Manufacturer As String, Producer As String, SerialNumber As String, BufLength As String) As Integer End Function End Class 'LibWrap 不过,我还是建议你采用方法 1 或 2。
of123 2012-11-13
  • 打赏
  • 举报
回复
两种调用约定:stdcall 或 cdecl。 VB 只能直接支持 stdcall。但你的 DLL 函数没有声明 __stdcall,是 cdecl 约定。 三种解决方法: 1 改 DLL 源码,加上 __stdcall。这个最简单。 2 如果没有改 DLL 源码的条件,可以再写一个 DLL 作中转,这个 DLL 的函数声明为 __stdcall 约定,它来调用原函数。 3 最麻烦的,在 VB 中声明一个类,来支持 cdecl 调用约定。下面是一个例子: Imports System Imports Microsoft.VisualBasic Imports System.Runtime.InteropServices Public Class LibWrap ' Visual Basic does not support varargs, so all arguments must be ' explicitly defined. CallingConvention.Cdecl must be used since the stack ' is cleaned up by the caller. ' int printf( const char *format [, argument]... ) <DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _ Overloads Shared Function printf ( _ format As String, i As Integer, d As Double) As Integer End Function <DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _ Overloads Shared Function printf ( _ format As String, i As Integer, s As String) As Integer End Function End Class 'LibWrap Public Class App Public Shared Sub Main() LibWrap.printf(ControlChars.CrLf + "Print params: %i %f", 99, 99.99) LibWrap.printf(ControlChars.CrLf + "Print params: %i %s", 99, _ "abcd") End Sub 'Main End Class 'App
threenewbee 2012-11-12
  • 打赏
  • 举报
回复
1L正解。API是stdcall调用约定方式,这种方式从最后一个参数往前将参数压入堆栈,并且自动清理堆栈,而默认的C程序使用cdecl约定,这种方式需要调用者手工清除堆栈,如果你试图在VB中调用一个cdecl约定的函数,就会因为堆栈不平衡出现DLL调用约定错误。
几罗星人 2012-11-11
  • 打赏
  • 举报
回复
引用 1 楼 of123 的回复:
VB 要求 API 函数是 __stdcall 规格。 Public Declare Fuction GetInfo Lib "RationalScaleScale.dll"(Byref Manufacturer As Byte, Byref Producer As Byte, Byref SerialNumber As Byte, Byref BufLength As Byte) 不……
他这个不对吧。原来的C/C++的声明是

USHORT GetInfo(
char *Manufacturer,
char *Producer,
char *SerialNumber,
char *BufLength);
而*代表指针,char 代表是字符串类型,ushort表示整数数据类型,所以如果要改乘VB,应该改成这样

Public Declare Fuction GetInfo Lib "RationalScaleScale.dll"(ByVal Manufacturer As Long, ByVal Producer As Long, ByVal SerialNumber As Long, ByVal BufLength As Long)As Long'其实根据原来的声明,ushort应该转成VB的Integer,但是习惯上都用Long,范围更大,肯定不会出问题
在调用的时候这样:

Dim Manufacturer As String, _
    Producer As String, _
    SerialNumber As String, _
    BufLength As String'这里声明字符串类型的变量

Manufacturer =xxx'需要的值
Producer =xxx'需要的值
SerialNumber =xxx'需要的值
BufLength =xxx'需要的值

GetInfo StrPtr(Manufacturer),StrPtr(Producer),StrPtr(SerialNumber),StrPtr(BufLength)
StrPtr函数取回一个字符串变量的地址
你试一下这样行不行吧。如果可以别忘了回来通知我一下,因为语法转换我也可能要做,但是没机会实践一下自己的想法。 附录1:之所以要这样做,是因为指针实际上取得是变量的地址,如果在C/C++里,可以通过地址直接操作对象,数据;但是在VB里没有指针这个概念,也不能直接通过地址操作对象。这里的函数要求传入的是指针,实际上就是一个地址,通过用StrPtr函数降地址传进去应该是可以的。这相当于VB读取指针。 附录2:这个虽然和你的问题无关,不过你可能会用到,这是我见到实际可行的。如果函数返回的也是一个指针,按理来说VB是没办法使用的,但是实际上却可以。只要你知道这个指针的指向到底是一个什么东西,就有办法调用。例如:

Dim SysTray As cSysTray                         ' 系统托盘类变量
Dim ClassAddr As Long                           ' 长整形类对象指针

' 取回长指针类对象,这被保存在用户数据的窗口结构。然后用户控制被子类。
ClassAddr = GetWindowLong(hwnd, GWL_USERDATA) ' 取回区指标对象
CopyMemory SysTray, ClassAddr, 4            ' 复制一个有被引用指针的对象到变量
SysTray.SendEvent lParam, wParam            ' 发送窗口消息\用户事件控制
首先SysTray是一个cSysTray对象,但是他没有实例化(就是用Set SysTray = New cSysTray来创建一个新的对象),而GetWindowLong在这里返回的ClassAddr就是一个cSysTray对象的地址(指针)。这时候就可以用CopyMemory函数,将ClassAddr地址指向的所有内容原封不动地放到SysTray变量里,这时候的SysTray变量就有了ClassAddr地址所指向的cSysTray对象,所以下面的一条语句就可以用SysTray变量名来操作ClassAddr地址所指向的对象。这也就相当于是VB操作指针。
shanyonggang 2012-11-10
  • 打赏
  • 举报
回复
产生DLL调用约定错误!是什么原因?
shanyonggang 2012-11-09
  • 打赏
  • 举报
回复
ret = GetInfo(bytManufacturer(0), bytProducer(0), bytSerialNumber(0), bytBufLength(0)) 产生DLL调用约定错误!
shanyonggang 2012-11-09
  • 打赏
  • 举报
回复
产生调用约定错误!
of123 2012-11-08
  • 打赏
  • 举报
回复
VB 要求 API 函数是 __stdcall 规格。 Public Declare Fuction GetInfo Lib "RationalScaleScale.dll"(Byref Manufacturer As Byte, Byref Producer As Byte, Byref SerialNumber As Byte, Byref BufLength As Byte) 不明白为什么你的缓冲区长度还是 char 指针型。 调用时: Dim bytManufacturer(15) As Byte, bytProducer(15) As Byte Dim bytSerialNumber(9) As Byte, bytBufLength(3) As Byte Dim ret As Integer ret = GetInfo(bytManufacturer(0), bytProducer(0), bytSerialNumber(0), bytBufLength(0))

7,763

社区成员

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

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