研究了一段时间欺骗VB编译器,利用VB制作DLL以后,发现所做出来的DLL还是得依赖于MSVBVM60.DLL存在,只能为VB所调用,不能为其他程序共享,这令我十分郁闷,VB看来是没得希望做出通用DLL了!所以最近研究VC+VB制作程序,我VB用得熟悉点,有点小小的感情与大家共享,不足之处请大家指正。
    VC和VB联合编程最简单也是最方便的便是由VC制作出标准的DLL然后VB再调用。由于涉及到的参数类型比较多,我只说其中的1中,字串型数据。呵呵,这也是我研究得比较多的一种数据类型。
  VB的字串默认为UNICODE方式,而VC为ANSI。为了实现从VC制作出的DLL中成功地返回正确的字串,需要用到函数 SysAllocString,它的作用是为字串分配内间,并返回 BSTR型的指针,指向这个类型的字串。
  BSTR型数据, 所指向的内存地址相当于一个wchar_t*,即指向一个UNICODE字串的指针。在VC中 wchar_t是这样定义的: typedef unsigned short wchar_t; 从这里我们可以清楚地看到,所谓的宽字符就是无符号短整数。
    但BSTR与wchar_t* 型指钟也是有点区别的:BSTR往后退4Bytes(在内存中)的地址中所存的一个DWORD值表示它的长度。这与VB中的字串存放原理一样,所以可以用BSTR型串返回给VB调用。不必担心内存的释放问题,由SysAllocString分配的内存将被调用程序自动释放。
  我们还需要注意的一个问题是,VB中调用函数的方式为标准调用,即__stdcall调用,WINDOWS中的API函数所采用的就是__stdcall标准。在VC中是这样定义的: tyepdef WINAPI __stdcall。这说明WINAPI与__stdcall是一样的。而VC中的函数默认为C标准的调用即 __cdec。所以如果想做出通用的DLL,我们需要在函数的前面加上 __stdcall申明为标准调用。
  好了,话就说这么多了,下面我们来看看这个code.dll:
  ode.dll中含有的函数如下 (经测试,在VC60、VB60中正常运行!):
    BSTR __stdcall Base64_Encode(LPSTR s); //Base64加密函数 (支持中英文混合加密)  BSTR __stdcall Base64_Decode(LPSTR s); //Base64解密函数
  BSTR __stdcall Rand_Encode(LPSTR s); //随机数加密函数 (支持中英文混合加密)
  BSTR __stdcall Rand_Decode(LPSTR s); //随机数解密函数
    BSTR __stdcall GetWeekday(LPSTR s); //获取指定日期的星期数,格式如:"2008-5-22"(VB中Date类型也支持)
    int Hex2Dec(LPSTR s);    //将十六进制的s字符串转化为十进制数 (如果输入的不是十六进制数,则返回-1)

C++中的调用方式,其他函数同理:

  //OnOk函数中代码(点击IDC_OK按钮以后)
  LPSTR sdate="2008-5-22";
  BSTR tst;
  typedef BSTR (__stdcall * pfunc)(LPSTR); //函数原型申明
  HINSTANCE hdll=LoadLibrary("code.dll");  //调用dll模块
  pfunc pGetWeekday=(pfunc)GetProcAddress(hdll,"GetWeekday"); 
     //取得DLL中函数的地址
  tst=pGetWeekday(sdate);
  AfxMessageBox((LPSTR)tst);
VB中的调用方式(其他函数同理):

Private Declare Function GetWeekday Lib "code.dll" (ByVal x As String) As String 
'函数申明
Private Sub Command1_Click()
  Dim strday as string
   strday=GetWeekday(Now) '直接调用,显示现在星期数
  MsgBox strday
End Sub

  • 标 题:答复
  • 作 者:不问年少
  • 时 间:2008-05-23 11:19:35

  说了半天,忘记传源代码了,呵呵!

上传的附件 code.rar