此篇文章是在實際開發過程中遇到的問題,得到過同事的協助,在此一併感謝。
在SolidWorks二次開發過程中,使用非同步模式,如下代碼在使用中出現了問題(可能出問題的地方,已作了注視)
BOOL CSWFun::GetProfileLength(CComPtr<ILoop2>pLoop, double &dLength) { long edgeCount = 0; pLoop->GetEdgeCount(&edgeCount); if (edgeCount > 0) { double dLenthTemp = 0.0; VARIANT_BOOL isClosed = VARIANT_FALSE; VARIANT_BOOL isPeriodic = VARIANT_FALSE; VARIANT_BOOL vbRet = VARIANT_FALSE; IEdge **pEdgeArr = NULL; pEdgeArr = new IEdge* [edgeCount]; ZeroMemory(pEdgeArr, edgeCount*sizeof(IEdge*)); pLoop->IGetEdges(pEdgeArr); for (int i=0; i<edgeCount; ++i) { CComPtr<IEdge> pEdge = pEdgeArr[i];//可能指標為NULL if (pEdge == NULL) { continue; } CComPtr<ICurve> pCurve; pEdge->IGetCurve(&pCurve); if (NULL == pCurve) { continue; } double dStart = 0.0; double dEnd = 0.0; pCurve->GetEndParams(&dStart, &dEnd, &isClosed, &isPeriodic, &vbRet); //可能返回失敗 if (vbRet != VARIANT_FALSE) { double dTemp = 0.0; pCurve->GetLength2(dStart, dEnd, &dTemp); if (dTemp > 0) { dLenthTemp += dTemp; } } } delete []pEdgeArr; pEdgeArr = NULL; dLength = dLenthTemp; } return TRUE; }
改成如下代碼後,則正常
BOOL CSWFun::GetProfileLength(CComPtr<ILoop2>pLoop, double &dLength){long edgeCount = 0;pLoop->GetEdgeCount(&edgeCount);if (edgeCount > 0){double dLenthTemp = 0.0;VARIANT_BOOL isClosed = VARIANT_FALSE;VARIANT_BOOL isPeriodic = VARIANT_FALSE;VARIANT_BOOL vbRet = VARIANT_FALSE;CComVariant vEdgeArray;pLoop->GetEdges(&vEdgeArray);if (V_VT(&vEdgeArray) == VT_EMPTY){return FALSE;}SAFEARRAY *pSaveEdgeArray = V_ARRAY(&vEdgeArray);LPDISPATCH *pEdgeDispArray = NULL;SafeArrayAccessData(pSaveEdgeArray, (void**)&pEdgeDispArray);if (pEdgeDispArray == NULL){return FALSE;}for (int i=0; i<edgeCount; ++i){CComQIPtr<IEdge> pEdge = pEdgeDispArray[i];if (pEdge == NULL){continue;}CComPtr<ICurve> pCurve;pEdge->IGetCurve(&pCurve);if (NULL == pCurve){continue;}double dStart = 0.0;double dEnd = 0.0;pCurve->GetEndParams(&dStart, &dEnd, &isClosed, &isPeriodic, &vbRet);if (vbRet != VARIANT_FALSE){double dTemp = 0.0;pCurve->GetLength2(dStart, dEnd, &dTemp);if (dTemp > 0){dLenthTemp += dTemp;}}}dLength = dLenthTemp;}return TRUE;}
無效的介面函數,主要是以'I'開頭的擷取或設定資料的函數,文中對應的是IGetEdges,改為GetEdges則正常。API協助的說明如下:The COM interface is recommended for all add-in DLL projects. For executable (.exe) implementations, you can use the COM interface unless the method or property passes an array. In this case, use the equivalent
Dispatch method that uses a VARIANT to encapsulate the array.所以,開發過程中,如果是非同步模式,需要擷取array類型的資料,避免使用“I”開頭的函數。