第一種類型:數值傳遞
注意:在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