关于vb调用vc动态库:参数指针的传递错误。十万火急!!!up有5分,解决给100分

yhb7805 2002-11-27 10:53:03
关于vb调用动态库:参数指针的传递

现有用VC生成的win32动态库,原码如下
/////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>


void changeText(PVOID dest, PVOID source)
{
unsigned char s[12];



memset(s, 0, 12);
memset(s, 'D', 10);
memcpy(dest, source, 8);
}
该动态库用VC 是可以调用的。

在VB中声明该动态库如下:
Private Declare Sub Copy Lib "chang.dll" Alias "changeText" ( _
lpDest As Any, _
lpSource As Any)

在CommandButton :do中做如下操作
———————————————————————————
Private Sub do_Click()
Dim c1 As String
Dim b1 As String
b1 = "bbbbbbbbbbbbbb"
Copy c1, b1
Text1.Text = c1
End Sub
———————————————————————————
当我点击按扭do时,提示我
Run-time error'49'

Bad DLL calling convention
我查阅了MSDN,说是我传递的参数错误,可是我做了如下操作
声明windows的win32函数:CopyMemory 如下
Private Declare Sub CopyMemory Lib "C:\WINNT\system32\KERNEL32.DLL" Alias "RtlMoveMemory" ( _
lpDest As Any, _
lpSource As Any, _
ByVal cbCopy As Long)

同时作了一个CommandButton :Ptrchange
————————————————————————

Private Sub Ptrchange_Click()
Dim i As Integer
Dim f As Long
Dim ch As String
Dim bArray(1 To 4) As Byte
s1 = "aaaaaaaa"
f = &H4030201
CopyMemry ch, s1, 6

Text1.Text = ch


End Sub

——————————————————————————
在点击Ptrchange后,成功的在Text1里面显示了"aaaaaaaa"

这就是问题的中心了,为什么我的动态库不能被调用呢?是不是我创建的动态库有问题,或者说为VB 创建的
动态库与为VC创建动态库有区别,需要特殊的操作么?我现在在外地做工程,情况紧急,请各位高手多多帮忙!
...全文
117 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
用户 昵称 2002-11-29
  • 打赏
  • 举报
回复
VB pass string to VC
Change the ByRef to ByVal in the Declare-statement. Sending it as a ByRef will send it as it is defined internally in VB. ByVal will send the actual string and not the internal struct (something like length + string).
Public Declare Sub DeReceiveStringFromVB Lib "MyVCDLL" ( _
ByVal s1 As String, ByVal s2 As String)

DeReceiveStringFromVB "aaa", "bbb"


__declspec( dllexport ) void __stdcall DeReceiveStringFromVB(LPCSTR lp1,LPCSTR lp2)
{
std::stringstream stmp;
stmp<<"ReceiveStringFromVB("<<lp1<<","<<lp2<<")";
OutputDebugString(stmp.str().c_str());
}


VC pass string to VB
__declspec( dllexport ) void __stdcall Long2String2(long lpdata,LPSTR pszString, LONG cSize)
{

wsprintf(pszString,"%d",lpdata);
}
Private Declare Sub Long2String2 Lib "MyVCDLL" ( _
ByVal pFunc As Long, ByVal sMyString As String, ByVal cBufferSize As Long)

Dim sFillTest As String
sFillTest = Space$(260)
Long2String2 wParam, sFillTest, 260
用户 昵称 2002-11-29
  • 打赏
  • 举报
回复
现在越来越多的人采用VB与VC的混合编程:用VB快速开发出漂亮的界面以及外围处理程序,再用VC编写底层的各种操作,例如内存的操作、IO端口的操作等,VC中还可以嵌入汇编语言进行更底层的操作。
  一般的做法是将VC程序编译成DLL,在VB中用Declare语句声明DLL中的函数,例如:
  Declare Function SendCommand Lib ″c:\program files\devstudio\wjfprojects\Hr0506dllMnsr\debug\Hr0506dllMnsr.dll″(CmdNum As Integer) As Boolean
  声明以后,函数SendCommand 就可以当作VB自己的函数使用了。
  但是,怎样将VC中的各种消息(例如各种底层的状态)及时通知VB并且VB能够及时处理呢?这是VB的一个缺陷:不能方便地处理自定义的Windows消息。例如在VC中自定义了两条消息:MW_TAPI_DATACOME,MW_TAPI_BUSY,在C语言中,用PostMessage(hWnd,MW_TAPI_CONNECTED,0,0);语句可以很方便地将MW_TAPI_CONNECTED消息传递给窗体(窗体句柄为hWnd),在主回调函数中就可以处理了。但是要把这条消息传递给VB,并让VB处理这条消息,并不太容易。虽然在VB5.0以上的版本中,可以定义自己的事件(EVENT),但比较麻烦。这里介绍一种简单的方法,让VB巧妙地处理自定义的消息:
  1.首先将VB窗体中TextBox控件Text1的句柄传递给DLL(注意:VB中的TextBox控件有hWnd属性)。
  VB中: ′声明DLL中的函数
  Declare Function SendhWnd Lib ″c:\program files\devstudio\wjfprojects\Hr0506dllMnsr\debug\ Hr0506dllMnsr.dll″ ((ByVal hWnd As Long) As Boolean
  ′传递text1的句柄
  SendhWnd(text1.hWnd)
  VC中://句柄接收函数
   declspec(dllexport) BOOL GethWnd(HWND hWnd1)
  { hWnd=hWnd1;
  if (hWnd==NULL)
  { return FALSE; }
  return TRUE;}
  2.在VC中用API函数SetWindowText取代PostMessage直接发送消息给VB中的Text1控件:
  SetWindowText(hWnd,″ MW_TAPI_DATACOME ″);
  3.在Text1_Change事件中处理消息:
  Private Sub Text1_Change()
  Select case Text1.text
  case W_TAPI_DATACOME:
  ′消息处理语句
  case MW_TAPI_BUSY:
  ′消息处理语句
  default:
  ′其他处理语句
  End Select
  End Sub
  以上方法在作者编写的“TAPI远程监控系统”中使用,效果很好。
zyl910 2002-11-28
  • 打赏
  • 举报
回复
int _stdcall myFunction1(int para1, int para2)
{
int sum;

sum = para1 + para2;
return sum;
}

int _stdcall myFunction2(int para1, int para2)
{
int sum;

sum = para1 + para2;
return sum;
}



Private Declare Function myFunction1 Lib "mydll.dll" ( _
ByVal argu1 As Long, ByVal argu2 As Long) As Long

Private Declare Function myFunction2 Lib "mydll.dll" ( _
ByVal argu1 As Long, ByVal argu2 As Long) As Long
yhb7805 2002-11-28
  • 打赏
  • 举报
回复

用C编写的动态库的一个函数原形
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>


int myFunction(unsigned char *inData,
int inDataLength,
unsigned char *outData,
int *outDataLength)
{
memcpy(outData, inData, inDataLength);
*outDataLength = inDataLength;
return 0;

}

/* 下面的函数中之所以用long型变量,而不用int型, */
/* 是因为VB只能支持32位长度的调用。 */
/* (网上看的)如果使用int 型最后提示 */
/* 错误49: 参数类型错误 */


long myFunction1(long para1, long para2)
{
long sum;

sum = para1 + para2;
return sum;
}

long myFunction2(long para1, long para2)
{
long sum;

sum = para1 + para2;
return sum;
}


生成动态库 "mydll.DLL"
在VB中声明 "myFunction" 如下
Private Declare Function myFunction1 Lib "mydll.dll" ( _
ByVal argu1 As Long, ByVal argu2 As Long) As Long

Private Declare Function myFunction2 Lib "mydll.dll" ( _
ByVal argu1 As Integer, ByVal argu2 As Integer) As Integer


Dim para1 As Long
Dim para2 As Long
Dim para3 As Byte
Dim para4 As Byte
Dim para5 As Integer
Dim para6 As Integer
Dim sum1 As Long
Dim sum2 As Integer

para1 = 5
para2 = 5
para5 = 5
para6 = 5

sum1 = myFunction1(para1, para2)
Debug.Print Hex(sum1)

sum2 = myFunction2(para5, para6)
Debug.Print Hex(sum1)


返回:错误49: 参数类型错误

将myFunction1重新定义如下:

int myFunction1(int para1, int para2)
{
int sum;

sum = para1 + para2;
return sum;
}

还是错误49。
我应该怎样声明我的函数呢??
yhb7805 2002-11-28
  • 打赏
  • 举报
回复
up
programerfeng 2002-11-28
  • 打赏
  • 举报
回复
up
yhb7805 2002-11-28
  • 打赏
  • 举报
回复
问题是我可以用vc调用,用vb 时,它说参数传递错误,参数类型不匹配
liuto 2002-11-28
  • 打赏
  • 举报
回复
好像有问题。我不太懂VB,但是dim xxx as String会给xxx分配多大内存呢?
如果没有分配,你那个dll的函数只怕有问题了。

7,540

社区成员

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

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