0

如何将一个双精度数组从 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++ 空闲文件:

[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;
}
4

2 回答 2

1

你的问题在这里:

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

与此等效的 VB 将是:

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

| VT_R8is 评估为布尔值,true因为:1)==优先于|,因此执行比较,然后VT_R8评估。并且 2) 任何非零的东西在 C 中都等于“真”。由于VT_R8它自己被评估(而不是作为比较的一部分),它总是true.

您需要使用括号,以便按照您想要的顺序评估您的语句。

于 2013-10-24T17:39:17.063 回答
0

这是答案..我必须销毁原始的安全阵列数据,创建一个新的安全阵列来填充地图中的数据,然后使用 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;

}
于 2013-11-13T05:29:14.557 回答