zoukankan      html  css  js  c++  java
  • VB调用VC dll的返回方式

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

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



    .def文件
    EXPORTS TestCalc

    VB部分
    声明:

    [vb] view plaincopy
     
    1. Private Declare Function TestCalc Lib "Dll.dll" (ByVal Source As Long) As Long  


    调用:

    [vb] view plaincopy
     
    1. Dim Tint As Long  
    2. Tint = TestCalc(45)  
    3. MsgBox Tint, vbExclamation   





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

    VC++部分:

    [cpp] view plaincopy
     
    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部分:
    声明:

    [vb] view plaincopy
     
    1. Private Declare Function MidStr Lib "Dll.dll" (ByVal src As String, ByVal dest As String) As Long  


    调用:

    [vb] view plaincopy
     
    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++部分:

    [css] view plaincopy
     
    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部分
    声明:

    [vb] view plaincopy
     
    1. Private Declare Function TestByte Lib "Dll.dll" (ByRef src As Any, ByRef length As Long) As Long  


    调用:

    [vb] view plaincopy
     
    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部分:
         

    [cpp] view plaincopy
     
    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
     
    1. Public Declare Function StringArray Lib "xxx.DLL" (byval s() As String) As Integer  
    [vb] view plaincopy
     
    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函数原形:

    [cpp] view plaincopy
     
    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部分:

    声明:

    [cpp] view plaincopy
     
    1. extern "C" _declspec(dllexport) BOOL WINAPI cPowerAlarm(PowerAlarm* tagPower,PowerResult* tagResult)  

     结构体定义:

    [cpp] view plaincopy
     
    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部分:

    声明:

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

    结构体定义:

    [vb] view plaincopy
     
    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  
  • 相关阅读:
    简单工厂和抽象工厂有什么区别?
    常用的设计模式有哪些?
    常见的HTTP协议状态码?
    数据库分库分表(sharding)系列(二) 全局主键生成策略
    关于垂直切分Vertical Sharding的粒度
    数据库分库分表(sharding)系列(四) 多数据源的事务处理
    分库分表带来的完整性和一致性问题
    [置顶] 深入探析Java线程锁机制
    为啥RESTFULL如此重要?
    hadoop核心逻辑shuffle代码分析-map端
  • 原文地址:https://www.cnblogs.com/rosesmall/p/3928644.html
Copyright © 2011-2022 走看看