VB调用VC dll的返回
2013-12-23 03:46
555 查看
第一种类型:数值传递
注意:在VB中,默认变量传递方式为ByRef为地址,而传递值就是用ByVal,还要注意在C++中,
int类型的变量是32位的,在VB中要用long型变量来配合。
VC++部分:
[cpp] view
plaincopy
extern "C" _declspec(dllexport) int __stdcall TestCalc(int source)
{
//AFX_MANAGE_STATE(AfxGetStaticModuleState());
return(++source);
}
.def文件
EXPORTS TestCalc
VB部分
声明:
[vb] view
plaincopy
Private Declare Function TestCalc Lib "Dll.dll" (ByVal Source As Long) As Long
调用:
[vb] view
plaincopy
Dim Tint As Long
Tint = TestCalc(45)
MsgBox Tint, vbExclamation
第二种类型:传递字符串,主要用于字符串返回或者处理。
VC++部分:
[cpp] view
plaincopy
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部分:
声明:
[vb] view
plaincopy
Private Declare Function MidStr Lib "Dll.dll" (ByVal src As String, ByVal dest As String) As Long
调用:
[vb] view
plaincopy
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++部分:
[css] view
plaincopy
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部分
声明:
[vb] view
plaincopy
Private Declare Function TestByte Lib "Dll.dll" (ByRef src As Any, ByRef length As Long) As Long
调用:
[vb] view
plaincopy
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部分:
[cpp] view
plaincopy
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 部分:
声明:
[vb] view
plaincopy
Public Declare Function StringArray Lib "xxx.DLL" (byval s() As String) As Integer
[vb] view
plaincopy
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函数原形:
[cpp] view
plaincopy
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部分:
声明:
[cpp] view
plaincopy
extern "C" _declspec(dllexport) BOOL WINAPI cPowerAlarm(PowerAlarm* tagPower,PowerResult* tagResult)
结构体定义:
[cpp] view
plaincopy
// 电源报警模块 参数结构体
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部分:
声明:
[vb] view
plaincopy
Public Declare Function cPowerAlarm Lib "DataDiagnose.DLL" (ByRef myPower As h_PowerAlarm, ByRef myPowerResult As h_PowerResult) As Integer
结构体定义:
[vb] view
plaincopy
' 电源报警模块 参数结构体
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中,默认变量传递方式为ByRef为地址,而传递值就是用ByVal,还要注意在C++中,
int类型的变量是32位的,在VB中要用long型变量来配合。
VC++部分:
[cpp] view
plaincopy
extern "C" _declspec(dllexport) int __stdcall TestCalc(int source)
{
//AFX_MANAGE_STATE(AfxGetStaticModuleState());
return(++source);
}
.def文件
EXPORTS TestCalc
VB部分
声明:
[vb] view
plaincopy
Private Declare Function TestCalc Lib "Dll.dll" (ByVal Source As Long) As Long
调用:
[vb] view
plaincopy
Dim Tint As Long
Tint = TestCalc(45)
MsgBox Tint, vbExclamation
第二种类型:传递字符串,主要用于字符串返回或者处理。
VC++部分:
[cpp] view
plaincopy
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部分:
声明:
[vb] view
plaincopy
Private Declare Function MidStr Lib "Dll.dll" (ByVal src As String, ByVal dest As String) As Long
调用:
[vb] view
plaincopy
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++部分:
[css] view
plaincopy
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部分
声明:
[vb] view
plaincopy
Private Declare Function TestByte Lib "Dll.dll" (ByRef src As Any, ByRef length As Long) As Long
调用:
[vb] view
plaincopy
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部分:
[cpp] view
plaincopy
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 部分:
声明:
[vb] view
plaincopy
Public Declare Function StringArray Lib "xxx.DLL" (byval s() As String) As Integer
[vb] view
plaincopy
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函数原形:
[cpp] view
plaincopy
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部分:
声明:
[cpp] view
plaincopy
extern "C" _declspec(dllexport) BOOL WINAPI cPowerAlarm(PowerAlarm* tagPower,PowerResult* tagResult)
结构体定义:
[cpp] view
plaincopy
// 电源报警模块 参数结构体
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部分:
声明:
[vb] view
plaincopy
Public Declare Function cPowerAlarm Lib "DataDiagnose.DLL" (ByRef myPower As h_PowerAlarm, ByRef myPowerResult As h_PowerResult) As Integer
结构体定义:
[vb] view
plaincopy
' 电源报警模块 参数结构体
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的返回方式
- VB调用VC dll的返回方式
- VB调用VC++的DLL问题:1.无法返回参数,2.找不到入口点
- vb调用vc dll返回字符串类型
- VB中调用VC的DLL
- VB创建ActiveX dll 的COM服务器,VC调用VB COM方法
- VB中调用vc++ DLL文件中的函数问题
- 在VB应用程序中调用VC环境下开发的DLL
- VC 调用 VB 的DLL
- Visual Studio 2008中用VB调用VC++的DLL文件
- sqlserver 2000 触发器 存储过程调用外部dll,可以使vb,vc,delphi生成
- vs2010 vc++ 写成dll 被易语言dll 调用然后返回文本
- 在vb,vc中调用vb编写的DLL
- 再谈在VB中调用VC++开发的DLL
- sqlserver 2000 触发器 存储过程调用外部dll,可以使vb,vc,delphi生成
- 在VB应用程序中调用VC环境下开发的DLL
- 在VB应用程序中调用VC环境下开发的DLL
- vb调用vc++dll文件
- VS2010开发——vc++项目编写DLL提供vb.net调用
- VB调用VC写的DLL导出函数出现“Bad DLL call convention”的解决