VC与VB

VB调用VC dll的返回方式

第一种类型:数值传递
注意:在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部分
声明:

 
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;  

.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.        
  8.           char *arry[10];  
  9.            
  10.           for(i = 0;i < 10;i++)  
  11.           {  
  12.               arry[i] = "A";  
  13.           }  
  14.        
  15.           iBound.lLbound = 0;    // 数组起始位  
  16.           iBound.cElements = 10;    // 数据长度  
  17.            
  18.           // SafeArray描述符  
  19.           if (*VbArray == NULL)  
  20.           {  
  21.               if ((pSa = SafeArrayCreate(VT_BSTR,1,&iBound)) == NULL)  // 创建SafeArray描述符  
  22.               {  
  23.                   return FALSE;  
  24.               }  
  25.               *VbArray = pSa;                // 返回SafeArray描述符  
  26.           }  
  27.           else   
  28.           {   
  29.               if ((*VbArray)->cDims != 1)        // 释放为一维数组        
  30.                   return FALSE;       
  31.           }   
  32.        
  33.           for (i = iBound.lLbound;i < iBound.cElements;i++)  
  34.           {  
  35.               bSTR = SysAllocString((BSTR)arry[i]);  
  36.                
  37.               //     if(FAILED(safeArrayGetElement(*VbArray,(long*)&i,&bSTR))) // 从VbArray数组读取数据  
  38.               //{  
  39.               //    return FALSE;  
  40.               //}  
  41.               // 放数组元素到VbArray数组  
  42.                
  43.               if(FAILED(safeArrayPutElement(*VbArray,(long*)&i,bSTR)))  
  44.               {  
  45.                   return FALSE;  
  46.               }  
  47.               SysFreeString(bSTR); // 释放空间  
  48.        
  49.           }  
  50.           return 1;  
  51.       }

VB 部分:
声明:

[vb] view plaincopy
 
Public Declare Function StringArray Lib "xxx.DLL" (byval s() As String) As Integer  
  1. Sub StringArrayTest()  
  2.       Dim s()     As String  
  3.             
  4.         tmp = StringArray(s)  
  5.         Debug.Print s(0)  
  6. 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;  

在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)  

 结构体定义:

  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.       
  16. }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  

总结:

VC与VB间相互调用,可以通过VC的接口把数据传送到excel中,进行数据处理。

                                  改变自己,从现在做起-----------久馆

原文地址:https://www.cnblogs.com/zzw19940404/p/14071225.html