那位遇到过下面的dll调用问题??

zhuxj7996 2003-08-21 10:11:08
没有参数的dll调用没有问题,但是一加进参数给“49 Dll调用错误”的错误,为什么??参数对应绝对匹配,
...全文
76 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
学呀
zjsunjifu 2004-01-07
  • 打赏
  • 举报
回复
实际上,我觉得你的问题,在于两个方面:
1.是vc 与 vb里参数类型转换的问题
把VC++代码转换成VB代码

对于大多数VB的爱好者来说,在很多情况下都想通过使用API函数来实现一些比较高级的功 能或达到某种特殊效果,这就需要用到一些VC++的代码.

---- 本文就如何把VC++代码转换成VB代码给出了一些策略和方法.

---- 1.定义常量

---- 我们首先看第一个例子:

#define STD_COPY 1//COMMCTRL.H
---- 在VC++代码中用#define定义常量,而在VB中是用Const来定义,因此转换成VB的代码是:

Public Const STD_COPY=1
---- 第二个例子:

#define LB_SELECTSTRING0x018C //WINUSER.h
---- 这有一个问题,VC++中所有以"0x"开头的值是十六进制,而在VB中表示十六进制要用"&H"开头.因此转换成VB的代码为:

Const LB_SELECTSTRING = 0x018C
---- 第三个例子:

#define TCN_FIRST(0U-550U)
---- 这里有个特别的是定义的值是以"U"结尾,这是意味着该常量的类型是"unsigned long"(在VB中不支持 该数据类型).但是unsigned long和signed long(在VB中是Long)两种数据类型的值在存储方式上是一样 的,只是表现的形式不同.因此,我们只需要去掉末尾的"U"就可以了.

Const TCN_FIRST=(0-550) 这同样适合以"L"结尾的值
---- 另外,对于 #define CDDS_ITEMPOSTERASE(CDDS_ITEM | CDDS_POSTERASE),我们需要用"Or"来取代"|"

---- 2.结构的定义

---- 我们先看VC++定义的一个比较简单的结构:

typedef struct tagTBSAVEPARAMSA{
HKEY hkr;
LPCSTR pszSubKey;
LPCSTR pszValueName;
}TBSAVEPARAMSA,FAR* LPTBSAVEPARAMSA;
---- 首先我们需要把第一行的"typedef struct"转换成"Public Type"

Public Type tagTBSAVEPARAMSA
---- 然后处理结构成员,

HKEY hkr;
LPCSTR pszSubKey;
LPCSTR pszValueName;
---- 对于第一个成员类型HKEY.我们要知道VC++中的以"H"开头的大部分数据类型代表的是某种句柄.在VB中每一个Form对象和许多控件都有一个hWnd属性,它代表所属窗口的句柄.hWnd的类型是Long,并且所有用来存储句柄的变量类型都是Long.因此,该成员在VB中定义为:

hkr As Long
---- 同样的,VC++数据类型LPSTR和LPCSTR代表指向字符串的指针,在VB中可以当作String类型.因为当你传送结构给API时,VB将把结构中所有的String转换成指向ANSI字符串的指针.因此后两个成员在VB中表示为:
pszSubKey As String
pszValueName As String

对于最后一行"}TBSAVEPARAMSA,FAR*
LPTBSAVEPARAMSA;"我们只需要用
"End Type"取代

---- 就可以了.转换成VB代码后完整的结构为:
Public Type tagTBSAVEPARAMSA
hkr As Long
pszSubKey As String
pszValueName As String
End Type

---- 以下是VC++中数据类型对应到VB中的数据类型VC++数据类型VB数据类型

------------------------------------
short Integer
intLong
long Long
UNIT Long
ULONG Long
WORD,DWORD Long
WPARAM,LPARAM Long
WMSG,UMSGLong
HRESULT Long
BOOL Boolean
COLORREF Long
HWND,HDC,HBRUSH,HKEY,等等. Long
LPSTR,LPCSTRString
LPWSTR,OLECHAR,BSTR String
LPTSTRString
VARIANT_BOOLBoolean
unsigned char Byte
BYTE Byte
VARIANT Variant
(任何以*或**结尾的数据类型)Long
---- 3.函数的转换

---- 我们知道VB提供了API Viewer add-in,但是有很多API函数它并没有包括在内. 因此知道如何把VC++函数转换成VB的函数格式是非常重要的.先看第一个例子:

WINCOMMCTRLAPI HWND WINAPI
CreateStatusWindowsA(LONG style,
LPCSTR lpszTest,HWND hwndParent,UINT wID);
---- 这个函数创建一个StatusBar控件.从WINCOMMCTRLAPI可以得知该函数来自动态 链接库ComCtl32.dll.(有时,我们需要从MSDN中查找某函数对应的DLL) 然后我们知道该函数的返回类型是HWND,对应VB的类型是Long.最后,根据前面提到 类型对应表,很容易的转换相应的函数参数.

Public Declare Function CreateStatusWindowA Lib
"ComCtl32.dll" _
(Byval style As Long, _
Byval lpszText As String, _
Byval hwndParent As Long,Byval wID As Long) As Long
2.是你在vc 中的dll内函数到处时,应该加__stdcall(或WINAPI)关键字:
extern "C" __declspec(dllexport) int _stdcall(或WINAPI) get_cvq_fea(char img_name[],long *lng_doh_fea,long doh_len,long *lng_cvq_fea,long cvq_len)




zhuxj7996 2003-08-22
  • 打赏
  • 举报
回复
不对,c内的字符串数组在vb里其实就是string类型,而不是string数组,所以不能用省略的byref引用方法!!!!!
yateli 2003-08-22
  • 打赏
  • 举报
回复
应该这样
Declare Function get_cvq_fea Lib "f:\CDBIR\cvq_dll.Dll" _
(img_name As any, lf_hgm_fea As any, _
ByVal lf_hgm_len As Long, um_e1_fea As any, _
ByVal um_e1_len As Long) As Long
zhuxj7996 2003-08-21
  • 打赏
  • 举报
回复
设置对象是什么意思,应该是声明之后就马上能调用的才对阿??

楼上几位仁兄所提出的容易出错的地方我都试过且实践过没有问题。

这是c里边的函数声明:
extern "C" __declspec(dllexport) int get_cvq_fea(char img_name[],long *lng_doh_fea,long doh_len,long *lng_cvq_fea,long cvq_len)
{
return cvq_fea(img_name,lng_doh_fea,doh_len,lng_cvq_fea,cvq_len);

}
下面是vb中的声明:
Declare Function get_cvq_fea Lib "f:\CDBIR\cvq_dll.Dll" _
(ByVal img_name As String, ByRef lf_hgm_fea As Long, _
ByVal lf_hgm_len As Long, ByRef um_e1_fea As Long, _
ByVal um_e1_len As Long) As Long

此处是调用:
Dim lng_doh(64) As Long
Dim lng_cvq(24) As Long
Dim lng_rtn As Long

lng_i = 0

lng_rtn = get_cvq_fea("f:\a_0001.bmp", lng_doh(0), 64, lng_cvq(0), 24)
yateli 2003-08-21
  • 打赏
  • 举报
回复
将您的DLL声明拿来看看
道素 2003-08-21
  • 打赏
  • 举报
回复
我说说的看法,可能出错的原因是
buval和byref的约定
VB 中的参数通过引用来传递。因此,当 DLL 函数要求通过赋值来传递参数时,必须在该函数定义中包含关键字 ByVal。如果在函数定义中省略关键字 ByVal,有些情况下可能会导致这个错误
xiaorongli 2003-08-21
  • 打赏
  • 举报
回复
参数类型可能不匹配
比如function a(in1 as integer,str2 as string)
调用时要么直接参数值 a(12,"sfff")
如果参数是变量,则应类型转换a(cint(param1),cstr(param2))

1,066

社区成员

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

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