如何将双精度数组从 VB6 传递到 VC++.这段代码有什么问题

How to pass an array of doubles from VB6 to VC++..What is wrong with this code?

本文关键字:段代码 代码 问题 什么 VC++ 双精度 数组 VB6      更新时间:2023-10-16

如何将双精度数组从 VB6 传递到 VC++。这段代码有什么问题?

VB代码:dSelfCdArr是我的双精度值数组

Public Sub FilterDocTypeByPriv(colEventSets As Collection)
Dim lCount As Long
Dim oColItem As Object
Dim objDBEventSetRow As DB_EventSetRow
Dim evYes As Boolean
Dim dSelfCdArr() As Double
For lCount = 1 To colEventSets.Count
    Set objDBEventSetRow = colEventSets(lCount)
    ReDim Preserve dSelfCdArr(1 To lCount)
    dSelfCdArr(lCount) = CDbl(objDBEventSetRow.dSelf_cd)
Next
Call m_dtsAppForm.DocController.HasPrivCreateResultEventCode(m_dUserId, m_dPositionCd, m_dPPRCd, dSelfCdArr)
End Sub

C++ IDL 文件:

[id(51), helpstring("method HasPrivCreateResultEventCode")] HRESULT HasPrivCreateResultEventCode([in]double dUserId,[in]double dPosCd,[in]double dPPRCd, [in, out] VARIANT* pEventCode); 

C++代码:我在 VARIANT* pEventCode 的第一行收到错误的指针

STDMETHODIMP CDocumentController::HasPrivCreateResultEventCode(double dUserId,double dPosCd,double dPPRCd, VARIANT* pEventCode)
{   
HRESULT hr = E_FAIL;
AFX_MANAGE_STATE(AfxGetStaticModuleState())
if (V_VT(pEventCode) == VT_ARRAY | VT_R8)
{
    CComSafeArray<double> arrECode;
    arrECode.Attach(pEventCode->parray);
    double pVals;
    int iCount = arrECode.GetCount();
    CMap<double,double,bool,bool> mapEventCds;
    for(int iIndex = 0; iIndex < iCount; iIndex++)
    {                              
        double pVals = arrECode.GetAt(iIndex);
        mapEventCds.SetAt(pVals, false);
        std::cout << "element " << iIndex << ": value = " << pVals << std::endl;
    }
    CheckPrivViewResultEventCds(dUserId, dPosCd, dPPRCd, mapEventCds);
                //pEventCode->c
    double      dEventCd(0.0);
    bool        bPriv(false);
    POSITION    pos(mapEventCds.GetStartPosition());
    INT_PTR     nEventCnt(mapEventCds.GetCount());
    CComSafeArray<double> pSafeArraypEventCode = NULL;
    for(INT_PTR count(0); count < nEventCnt; ++count)
    {
        mapEventCds.GetNextAssoc(pos, dEventCd, bPriv);     
        if (bPriv)
        {   
            pSafeArraypEventCode.Add(dEventCd);
        }
    }
    pEventCode->parray = pSafeArraypEventCode.Detach();
    // Empty the CMap
    mapEventCds.RemoveAll();
}
return S_OK;
}

你的问题在这里:

if (V_VT(pEventCode) == VT_ARRAY | VT_R8)

与此等效的 VB 将是:

If V_VT(pEventCode) = VT_ARRAY Or True Then
//Do stuff
End If

| VT_R8正在计算布尔true,因为:1) ==优先于 | ,因此执行比较,然后评估VT_R8。和2)任何非零的东西在C中都等于"真"。 由于VT_R8本身进行评估(而不是作为比较的一部分),因此它始终true

您需要使用括号,以便按所需顺序计算语句。

这是答案。我必须销毁原始安全数组数据,创建一个新的安全数组来填充地图中的数据,然后使用 SafeArrayCopy 将新的安全数组数据复制到原始安全数组。成功了。

STDMETHODIMP CDocumentController::GetEventCodesWithAddDocumentationPriv(double dUserId,double dPosCd,double dPPRCd,SAFEARRAY** pArrayOfEventCode)
{ 
HRESULT lResult(S_OK); // return code for OLE functions
// checking if it is a one-dimensional array
if ( (*pArrayOfEventCode)->cDims != 1 ) 
{
    MsgWrite(MSG_DEFAULT, eMsgLog_Commit, _T("PVClinDocMiscCom"), eMsgLvl_Error, _T("CDocumentController::GetEventCodesWithAddDocumentationPriv() SafeArray pEventCode is not one dimensional"));
    return(E_FAIL);
}
// locking the array before using its elements
lResult=SafeArrayLock(*pArrayOfEventCode);
if (lResult != S_OK)
{   
    MsgWrite(MSG_DEFAULT, eMsgLog_Commit, _T("PVClinDocMiscCom"), eMsgLvl_Error, _T("CDocumentController::GetEventCodesWithAddDocumentationPriv() SafeArray pEventCode is not locked"));
    SafeArrayUnlock(*pArrayOfEventCode);
    return(E_FAIL);
}
double *pArrayOfElements; // pointer to the elements of the array
// using the array
pArrayOfElements=(double*) (*pArrayOfEventCode)->pvData;
CMap<double,double,bool,bool> mapEventCds;
// number of elements in the array
long lElements=(*pArrayOfEventCode)->rgsabound[0].cElements;
double lVal(0);
for (long lCount=0; lCount<lElements; lCount++) 
{ 
    lVal = pArrayOfElements[lCount]; 
    mapEventCds.SetAt(lVal, false); 
} 
CheckPrivViewResultEventCds(dUserId, dPosCd, dPPRCd, mapEventCds); 
SafeArrayUnlock(*pArrayOfEventCode);
lResult = SafeArrayDestroyData(*pArrayOfEventCode);
if (lResult != S_OK)
{   
    MsgWrite(MSG_DEFAULT, eMsgLog_Commit, _T("PVClinDocMiscCom"), eMsgLvl_Error, _T("CDocumentController::GetEventCodesWithAddDocumentationPriv() SafeArray could not be destroyed"));
    return(E_FAIL);
}
SAFEARRAYBOUND rgsabound[1]; //Create a one dimensional array
rgsabound[0].lLbound = (*pArrayOfEventCode)->rgsabound->lLbound; //Set the lowerbound for the array
rgsabound[0].cElements = (*pArrayOfEventCode)->rgsabound->cElements; //Set the upperbound for the array
//Create a new safearray of double to fill from the mapeventcodes
SAFEARRAY* newArray = SafeArrayCreate(VT_R8, 1, rgsabound);
double          dEventCd(0.0); 
bool            bPriv(false);
//Get the starting index of the SafeArray
long lEventCdIdx = (*pArrayOfEventCode)->rgsabound->lLbound;
POSITION pos(mapEventCds.GetStartPosition()); 
while(pos != NULL)
{ 
    mapEventCds.GetNextAssoc(pos, dEventCd, bPriv); 
    if (bPriv) 
    {   
        lResult = SafeArrayPutElement(newArray, &lEventCdIdx, &dEventCd);
        if (lResult != S_OK)
        {   
            MsgWrite(MSG_DEFAULT, eMsgLog_Commit, _T("PVClinDocMiscCom"), eMsgLvl_Debug, _T("CDocumentController::GetEventCodesWithAddDocumentationPriv() Failed to add element to array"));
        }
        lEventCdIdx++;
    }   
}
// Empty the CMap 
mapEventCds.RemoveAll(); 
//Copy the contents from new safearray to the existing safearray
SafeArrayCopy(newArray, pArrayOfEventCode);
//Destroy the new safearray
SafeArrayDestroy(newArray);
// releasing the array 
return S_OK;
}