第一种类型:数值传递
注意:在VB中,默认变量传递方式为ByRef为地址,而传递值就是用ByVal,还要注意在C++中,
int类型的变量是32位的,在VB中要用long型变量来配合。
VC++部分:

  1. extern "C" _declspec(dllexport) int __stdcall TestCalc(int source)
  2. {
  3. //AFX_MANAGE_STATE(AfxGetStaticModuleState());
  4. return(++source);
  5. }

.def文件
EXPORTS TestCalc

VB部分
声明:

  1. Private Declare Function TestCalc Lib "Dll.dll" (ByVal Source As Long) As Long

调用:

  1. Dim Tint As Long
  2. Tint = TestCalc(45)
  3. MsgBox Tint, vbExclamation

第二种类型:传递字符串,主要用于字符串返回或者处理。

VC++部分:

  1. extern "C" _declspec(dllexport) int __stdcall MidStr(CHAR * src,CHAR * dest)
  2. {
  3. //AFX_MANAGE_STATE(AfxGetStaticModuleState());
  4. strcpy(dest,src+1);
  5. return 0;
  6. }

.def文件
EXPORTS MidStr

VB部分:
声明:

  1. Private Declare Function MidStr Lib "Dll.dll" (ByVal src As String, ByVal dest As String) As Long

调用:

  1. Dim i As Long, s As String * 255
  2. tempstr = "Hello!World"
  3. i = MidStr(tempstr, s)  或者 i = MidStr("Hello!World", s)
  4. MsgBox s, vbExclamation

第三种类型:传递数组和变量指针,主要用于从dll中读出大量数据

VC++部分:

  1. extern "C" _declspec(dllexport) int __stdcall TestByte(BYTE *p,int *length)
  2. {
  3. //AFX_MANAGE_STATE(AfxGetStaticModuleState());
  4. *p=45;
  5. *(p+1)=46;
  6. *length=2;
  7. return 0;
  8. }

.def文件
EXPORTS TestByte

VB部分
声明:

  1. Private Declare Function TestByte Lib "Dll.dll" (ByRef src As Any, ByRef length As Long) As Long

调用:

  1. Dim a(0 To 10) As Byte
  2. Dim i As Integer, length As Long
  3. i = TestByte(a(0), length)
  4. MsgBox a(0) & " " & a(1) & vbCrLf & length, vbExclamation

第四种类型:传递字符串数组 
    
1、VB TO VC :
 
 VC部分:

  1. extern "C" _declspec(dllexport) int WINAPI StringArray(LPSAFEARRAY *VbArray)
  2. {
  3. DWORD i;
  4. BSTR bSTR;    // UNICODE 字符串
  5. LPSAFEARRAY pSa;
  6. SAFEARRAYBOUND iBound;
  7. char *arry[10];
  8. for(i = 0;i < 10;i++)
  9. {
  10. arry[i] = "A";
  11. }
  12. iBound.lLbound = 0;    // 数组起始位
  13. iBound.cElements = 10;    // 数据长度
  14. // SafeArray描述符
  15. if (*VbArray == NULL)
  16. {
  17. if ((pSa = SafeArrayCreate(VT_BSTR,1,&iBound)) == NULL)  // 创建SafeArray描述符
  18. {
  19. return FALSE;
  20. }
  21. *VbArray = pSa;                // 返回SafeArray描述符
  22. }
  23. else
  24. {
  25. if ((*VbArray)->cDims != 1)        // 释放为一维数组
  26. return FALSE;
  27. }
  28. for (i = iBound.lLbound;i < iBound.cElements;i++)
  29. {
  30. bSTR = SysAllocString((BSTR)arry[i]);
  31. //     if(FAILED(safeArrayGetElement(*VbArray,(long*)&i,&bSTR))) // 从VbArray数组读取数据
  32. //{
  33. //    return FALSE;
  34. //}
  35. // 放数组元素到VbArray数组
  36. if(FAILED(safeArrayPutElement(*VbArray,(long*)&i,bSTR)))
  37. {
  38. return FALSE;
  39. }
  40. SysFreeString(bSTR); // 释放空间
  41. }
  42. return 1;
  43. }

VB 部分:
声明:

  1. Public Declare Function StringArray Lib "xxx.DLL" (byval s() As String) As Integer
  1. Sub StringArrayTest()
  2. Dim s()     As String
  3. tmp = StringArray(s)
  4. Debug.Print s(0)
  5. End Sub

2、VB TO VC

VB的字符串数组是由BSTR组成的SafeArray类型,所以VB里DLL函数如此声明:
Private Declare FunctionMyFun Lib "MyDll" (ByVal strarr As Variant) As Long

建立MFC DLL工程,名为 ShowVBStrArr 编译生成 ShowVBStrArr.DLL
DLL函数原形:

  1. extern "C" BOOL __stdcall ShowVBStrArray(VARIANT VBpStrArray)
  2. {
  3. SAFEARRAY FAR *pStrArrTemp = NULL;
  4. long LBound;
  5. long UBound;
  6. BSTR HUGEP *pbstr;
  7. CString strtemp;
  8. if(V_VT(&VBpStrArray) != (VT_ARRAY | VT_BSTR))//判断是否为字符数组
  9. return FALSE;
  10. pStrArrTemp = V_ARRAY(&VBpStrArray);
  11. if (SafeArrayGetDim(pStrArrTemp)!=1)//判断是否为一维数组
  12. return FALSE;
  13. SafeArrayGetLBound(pStrArrTemp,1,&LBound);
  14. SafeArrayGetUBound(pStrArrTemp,1,&UBound);
  15. SafeArrayAccessData(pStrArrTemp, (void HUGEP* FAR*)&pbstr);
  16. for (int i=0;i<(UBound-LBound)+1;i++)
  17. strtemp+=LPWSTR(pbstr);
  18. MessageBox( 0,strtemp,"结果",MB_OK);
  19. SafeArrayUnaccessData(pStrArrTemp);
  20. return TRUE;
  21. }

在DLL工程的def文件里编辑如下:
EXPORTS
ShowVBStrArray

VB源码:
Option Explicit
Private Declare Function ShowVBStrArray Lib "xxx.dll" (ByVal pstr As Variant) As Long

Private Sub Command1_Click()
Dim prompt(1) As String
prompt(0) = "Hello"
prompt(1) = "World"

ShowVBStrArray prompt
End Sub

第五种 传结构体

由于需要根据需求向DLL中传入多种值或者需要从DLL中返回多种数据,都可以传结构体,不过得注意VB和VC的类型对应。具体操作如下: VC部分:

声明:

  1. extern "C" _declspec(dllexport) BOOL WINAPI cPowerAlarm(PowerAlarm* tagPower,PowerResult* tagResult)

结构体定义:

  1. // 电源报警模块 参数结构体
  2. typedef struct tagPowerAlarm
  3. {
  4. char* strSIM;       // SIM 卡号
  5. char* cStartTime;   // 开始时间
  6. char* cEndTime;     // 终止时间
  7. }PowerAlarm;
  8. // 电源报警模块 返回结果结构体
  9. typedef struct tagPowerResult
  10. {
  11. char cResultCH[20]; // 充电情况判断
  12. char cResultQuality[20]; // 电池品质判断
  13. char cResultHV[20]; // 过充判断
  14. char cResultLV[20]; // 欠压判断
  15. }PowerResult;

VB部分:

声明:

  1. Public Declare Function cPowerAlarm Lib "DataDiagnose.DLL" (ByRef myPower As h_PowerAlarm, ByRef myPowerResult As h_PowerResult) As Integer

结构体定义:

  1. ' 电源报警模块 参数结构体
  2. Public Type h_PowerAlarm
  3. strSIM     As String        ' SIM 卡号
  4. strStartTime As String      ' 开始时间
  5. strEndTime   As String      ' 终止时间
  6. End Type
  7. ' 电源报警模块 返回结果结构体
  8. Public Type h_PowerResult
  9. strResultCH As String * 20      ' 充电情况判断
  10. strResultQuality As String * 20 ' 电池品质判断
  11. strResultHV As String * 20      ' 过充判断
  12. strResultLV As String * 20      ' 欠压判断
  13. End Type

VB调用VC dll的返回方式的更多相关文章

  1. C#调用VC dll输出参数

    最近做项目需要把以前Vc写的程序整合到VS2005来,用c#写的,以前VC的动态连接库写好了,重写比较麻烦,让C#调用VC dll就好了.但碰到了一个问题:VC中作为输出参数的char*类型的变量应该 ...

  2. C#调用VC DLL堆栈不对称

    今天在调程序时,C#调用VC 编译的dll出现堆栈不对称,查了一下资料,转载在这里供大家参考. 问题描述:对 PInvoke 函数“xxFunction()”的调用导致堆栈不对称.原因可能是托管的 P ...

  3. C#调用C++ dll中返回值为字符串的函数问题

    C#调用C++ dll函数,如果返回值为字符串,我们使用string去接收就会报错,因为C++返回的是char*,是个指针,所以c# 要用 IntPtr 来接收. C++: //预编译的标头 .h e ...

  4. C# 调用 C++ Dll 类型转换的方式 全

    摘要:C#引用C++ Dll 所有类型转换的方式         //C++中的DLL函数原型为         //extern "C" __declspec(dllexport ...

  5. VB调用C# dll

    cd C:\Windows\Microsoft.NET\Framework\v4.0.30319注册regasm myTest.dll /tlb:myTest.tlb

  6. 关于C#动态调用VC Dll的方法(转)

    http://blog.csdn.net/null1/article/details/3953155

  7. QT调用VC DLL的例子(所有源码)

    http://blog.csdn.net/zhuce0001/article/details/20651025 http://blog.csdn.net/zhuce0001/article/detai ...

  8. c#/vb调用c编写的标准dll

    准备: 首先打开vc++ 6.0新建工程,选择Win32 Dynamic Link-Library,命名为stdLibrary 新建library.cpp文件,内容如下 #include <st ...

  9. 2015.5.9 C#编写DLL及C#调用C#DLL

    过程比C#调用VC++dll简单. 一.创建DLL 新建工程,类型选择类库,生成的结果就是dll 注意:在项目属性-应用程序中,注意三个地方,程序集名称和默认命名空间可以调整,但要一致,别的程序调用此 ...

随机推荐

  1. Bandwagon Host – 64M内存 1.5G硬盘 100G流量 年3.99美金

    BandwagonHost(习惯称作搬瓦工),属于IT7公司旗下的产品,搬瓦工虽然是新起的商家, 但是有实力雄厚的公司背景在一定程度上还是可以放心使用的. 很多用户在选择这款低价VPS的时候都担心是否 ...

  2. DataTable添加行的方法

    方法一: DataTable  tblDatas = new DataTable("Datas");DataColumn dc = null;dc = tblDatas.Colum ...

  3. TransactionScope只要一个操作失败,它会自动回滚,Complete表示事务完成

    实事上,一个错误的理解就是Complete()方法是提交事务的,这是错误的,事实上,它的作用的表示本事务完成,它一般放在try{}的结尾处,不用判断前台操作是否成功,如果不成功,它会自己回滚. #re ...

  4. 用最简单的例子理解迭代器模式(Iterator Pattern)

    迭代器模式的需求来自:需要对一些集合进行迭代,而迭代的方式可能有很多种. 说到迭代,动作大致包括设置第一个位置,获取下一个位置元素,判断是否迭代结束,获取当前位置元素,大致就这么些.把这些迭代动作封装 ...

  5. matlab进行地图仪的绘制

    % 绘制地球仪,并标出我们的位置 cla reset; load topo; [x,y,z] = sphere();%45是画出来的球面的经纬分面数 s = surface(x,y,z,'FaceCo ...

  6. OLEDB Excel 与C# 的数据流通方法

    一.             名词解释: OleDbCommand 是对数据源执行各种操作的SQL语句或者存储过程,连接access.excel等数据文件进行数据操作时候用到的,其实和sqlcomma ...

  7. Selenium2+python自动化39-关于面试的题

    前言 最近看到群里有小伙伴贴出一组面试题,最近又是跳槽黄金季节,小编忍不住抽出一点时间总结了下, 回答不妥的地方欢迎各位高手拍砖指点.   一.selenium中如何判断元素是否存在? 首先selen ...

  8. 谷歌死忠速查:可访问谷歌google搜索的IP们

    [见谅! 此文已废了,下面的办法已经无效了!]但是访问我博客并回复的哥们“问天何必”提供了一个方法,详见http://www.gaomn.com/,他提供了一个网站来访问google的,速度还算可以, ...

  9. [PHP] ubuntu16.04配置Lamp环境(搭建linux+apache+mysql+php7环境)

    reference : http://blog.csdn.net/Abyss_sliver/article/details/77621404 好久没有在Linux环境下进行开发了,比较常用的还是win ...

  10. Solution Explorer 和 Source Control Explorer 的 View History 异同

    如果查看别人对代码的修改,你可能会非常烦恼与在 Solution Explorer 中看历史版本看不全,如下: 实际上,你想看到的是对于整个解决方案,全部的历史版本,那应该跑去 Source Cont ...