VB调用VC dll的返回方式
第一种类型:数值传递
注意:在VB中,默认变量传递方式为ByRef为地址,而传递值就是用ByVal,还要注意在C++中,
int类型的变量是32位的,在VB中要用long型变量来配合。
VC++部分:
- extern "C" _declspec(dllexport) int __stdcall TestCalc(int source)
- {
- //AFX_MANAGE_STATE(AfxGetStaticModuleState());
- return(++source);
- }
.def文件
EXPORTS TestCalc
VB部分
声明:
- Private Declare Function TestCalc Lib "Dll.dll" (ByVal Source As Long) As Long
调用:
- Dim Tint As Long
- Tint = TestCalc(45)
- MsgBox Tint, vbExclamation
第二种类型:传递字符串,主要用于字符串返回或者处理。
VC++部分:
- extern "C" _declspec(dllexport) int __stdcall MidStr(CHAR * src,CHAR * dest)
- {
- //AFX_MANAGE_STATE(AfxGetStaticModuleState());
- strcpy(dest,src+1);
- return 0;
- }
.def文件
EXPORTS MidStr
VB部分:
声明:
- Private Declare Function MidStr Lib "Dll.dll" (ByVal src As String, ByVal dest As String) As Long
调用:
- Dim i As Long, s As String * 255
- tempstr = "Hello!World"
- i = MidStr(tempstr, s) 或者 i = MidStr("Hello!World", s)
- MsgBox s, vbExclamation
第三种类型:传递数组和变量指针,主要用于从dll中读出大量数据
VC++部分:
- extern "C" _declspec(dllexport) int __stdcall TestByte(BYTE *p,int *length)
- {
- //AFX_MANAGE_STATE(AfxGetStaticModuleState());
- *p=45;
- *(p+1)=46;
- *length=2;
- return 0;
- }
.def文件
EXPORTS TestByte
VB部分
声明:
- Private Declare Function TestByte Lib "Dll.dll" (ByRef src As Any, ByRef length As Long) As Long
调用:
- Dim a(0 To 10) As Byte
- Dim i As Integer, length As Long
- i = TestByte(a(0), length)
- MsgBox a(0) & " " & a(1) & vbCrLf & length, vbExclamation
第四种类型:传递字符串数组
1、VB TO VC :
VC部分:
- extern "C" _declspec(dllexport) int WINAPI StringArray(LPSAFEARRAY *VbArray)
- {
- DWORD i;
- BSTR bSTR; // UNICODE 字符串
- LPSAFEARRAY pSa;
- SAFEARRAYBOUND iBound;
- char *arry[10];
- for(i = 0;i < 10;i++)
- {
- arry[i] = "A";
- }
- iBound.lLbound = 0; // 数组起始位
- iBound.cElements = 10; // 数据长度
- // SafeArray描述符
- if (*VbArray == NULL)
- {
- if ((pSa = SafeArrayCreate(VT_BSTR,1,&iBound)) == NULL) // 创建SafeArray描述符
- {
- return FALSE;
- }
- *VbArray = pSa; // 返回SafeArray描述符
- }
- else
- {
- if ((*VbArray)->cDims != 1) // 释放为一维数组
- return FALSE;
- }
- for (i = iBound.lLbound;i < iBound.cElements;i++)
- {
- bSTR = SysAllocString((BSTR)arry[i]);
- // if(FAILED(safeArrayGetElement(*VbArray,(long*)&i,&bSTR))) // 从VbArray数组读取数据
- //{
- // return FALSE;
- //}
- // 放数组元素到VbArray数组
- if(FAILED(safeArrayPutElement(*VbArray,(long*)&i,bSTR)))
- {
- return FALSE;
- }
- SysFreeString(bSTR); // 释放空间
- }
- return 1;
- }
VB 部分:
声明:
- Public Declare Function StringArray Lib "xxx.DLL" (byval s() As String) As Integer
- Sub StringArrayTest()
- Dim s() As String
- tmp = StringArray(s)
- Debug.Print s(0)
- 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函数原形:
- extern "C" BOOL __stdcall ShowVBStrArray(VARIANT VBpStrArray)
- {
- SAFEARRAY FAR *pStrArrTemp = NULL;
- long LBound;
- long UBound;
- BSTR HUGEP *pbstr;
- CString strtemp;
- if(V_VT(&VBpStrArray) != (VT_ARRAY | VT_BSTR))//判断是否为字符数组
- return FALSE;
- pStrArrTemp = V_ARRAY(&VBpStrArray);
- if (SafeArrayGetDim(pStrArrTemp)!=1)//判断是否为一维数组
- return FALSE;
- SafeArrayGetLBound(pStrArrTemp,1,&LBound);
- SafeArrayGetUBound(pStrArrTemp,1,&UBound);
- SafeArrayAccessData(pStrArrTemp, (void HUGEP* FAR*)&pbstr);
- for (int i=0;i<(UBound-LBound)+1;i++)
- strtemp+=LPWSTR(pbstr);
- MessageBox( 0,strtemp,"结果",MB_OK);
- SafeArrayUnaccessData(pStrArrTemp);
- return TRUE;
- }
在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部分:
声明:
- extern "C" _declspec(dllexport) BOOL WINAPI cPowerAlarm(PowerAlarm* tagPower,PowerResult* tagResult)
结构体定义:
- // 电源报警模块 参数结构体
- typedef struct tagPowerAlarm
- {
- char* strSIM; // SIM 卡号
- char* cStartTime; // 开始时间
- char* cEndTime; // 终止时间
- }PowerAlarm;
- // 电源报警模块 返回结果结构体
- typedef struct tagPowerResult
- {
- char cResultCH[20]; // 充电情况判断
- char cResultQuality[20]; // 电池品质判断
- char cResultHV[20]; // 过充判断
- char cResultLV[20]; // 欠压判断
- }PowerResult;
VB部分:
声明:
- Public Declare Function cPowerAlarm Lib "DataDiagnose.DLL" (ByRef myPower As h_PowerAlarm, ByRef myPowerResult As h_PowerResult) As Integer
结构体定义:
- ' 电源报警模块 参数结构体
- Public Type h_PowerAlarm
- strSIM As String ' SIM 卡号
- strStartTime As String ' 开始时间
- strEndTime As String ' 终止时间
- End Type
- ' 电源报警模块 返回结果结构体
- Public Type h_PowerResult
- strResultCH As String * 20 ' 充电情况判断
- strResultQuality As String * 20 ' 电池品质判断
- strResultHV As String * 20 ' 过充判断
- strResultLV As String * 20 ' 欠压判断
- End Type
VB调用VC dll的返回方式的更多相关文章
- C#调用VC dll输出参数
最近做项目需要把以前Vc写的程序整合到VS2005来,用c#写的,以前VC的动态连接库写好了,重写比较麻烦,让C#调用VC dll就好了.但碰到了一个问题:VC中作为输出参数的char*类型的变量应该 ...
- C#调用VC DLL堆栈不对称
今天在调程序时,C#调用VC 编译的dll出现堆栈不对称,查了一下资料,转载在这里供大家参考. 问题描述:对 PInvoke 函数“xxFunction()”的调用导致堆栈不对称.原因可能是托管的 P ...
- C#调用C++ dll中返回值为字符串的函数问题
C#调用C++ dll函数,如果返回值为字符串,我们使用string去接收就会报错,因为C++返回的是char*,是个指针,所以c# 要用 IntPtr 来接收. C++: //预编译的标头 .h e ...
- C# 调用 C++ Dll 类型转换的方式 全
摘要:C#引用C++ Dll 所有类型转换的方式 //C++中的DLL函数原型为 //extern "C" __declspec(dllexport ...
- VB调用C# dll
cd C:\Windows\Microsoft.NET\Framework\v4.0.30319注册regasm myTest.dll /tlb:myTest.tlb
- 关于C#动态调用VC Dll的方法(转)
http://blog.csdn.net/null1/article/details/3953155
- QT调用VC DLL的例子(所有源码)
http://blog.csdn.net/zhuce0001/article/details/20651025 http://blog.csdn.net/zhuce0001/article/detai ...
- c#/vb调用c编写的标准dll
准备: 首先打开vc++ 6.0新建工程,选择Win32 Dynamic Link-Library,命名为stdLibrary 新建library.cpp文件,内容如下 #include <st ...
- 2015.5.9 C#编写DLL及C#调用C#DLL
过程比C#调用VC++dll简单. 一.创建DLL 新建工程,类型选择类库,生成的结果就是dll 注意:在项目属性-应用程序中,注意三个地方,程序集名称和默认命名空间可以调整,但要一致,别的程序调用此 ...
随机推荐
- oracle监听理解 命名理解
一.监听器是oracle基于服务器端的一种网络服务,主要作用是监听客户端的连接请求,并将请求转发给服务器. 监听器基于端口的,每个监听器会占用一个端口.默认监听端口1521. oracle家目录下的n ...
- solaris 常用软件安装
http://blog.csdn.net/cuterhei/article/category/1259722
- 《学习opencv》笔记——矩阵和图像操作——cvAbs,cvAbsDiff and cvAbsDiffS
矩阵和图像的操作 (1)cvAbs,cvAbsdiff,cvAbsDiffS 它们的结构为: void cvAbs( //取src中元素的绝对值,写到dst中 const CvArr* src, co ...
- HDU2838 Cow Sorting 树状数组 区间求和加逆序数的应用
这题目意思非常easy,就是给你一个数组,然后让你又一次排好序,排序有要求的,每次仅仅能交换两个元素的位置,交换须要一个代价 就是两个元素之和,问你把数组重小到大排好最少须要多少代价 可能一開始想不到 ...
- Matlab绘图控制命令
[转载] 图形的控制与表现 (Figure control and representation) MATLAB提供的用于图形控制的函数和命令: axis: 人工选择坐标轴尺寸. clf: ...
- <jsp:directive.page import=""/>的用法和解释
<jsp:directive.page import="zero.space.ch03.BookBean"/> 相当于 <%@ page import ...
- waitdialogform z
namespace DevExpress.Utils { using DevExpress.LookAndFeel; using DevExpress.Skins; using DevExpress. ...
- pytest文档23-使用多个fixture和fixture直接互相调用
使用多个fixture 如果用例需要用到多个fixture的返回数据,fixture也可以return一个元组.list或字典,然后从里面取出对应数据. # test_fixture4.py impo ...
- 新手学习selenium路线图(老司机亲手绘制)-学前篇
前言: 本来这篇是只在微信公众号(yoyoketang)上发布的,最近一搜,发现本很多人copy(copy公众号的,图片是加载不出来的)了,还没注明出处,不想多说什么,博客上也同步更新这篇吧! 最近群 ...
- 《C++反汇编与逆向分析技术揭秘》之12——继承
识别类和类之间的关系 在父类中声明为私有的成员,虽然子类对象无法直接访问,但是在子类对象的内存结构中,父类私有的成员数据依然存在. 在没有提供构造函数的时候,系统会尝试提供默认的构造函数: 当子类中没 ...