I am facing a problem while invoking a com ( developed in VC++) method from .NET, I have enclosed below both VC++ & .NET Code, when i invoke this component from VB 6.0 it works fine and both the out parameter pvarAccessList & pvarErrorMsg gets filled and returned properly. pvarAccessList returns a byte array and pvarErroMsg returns a string ... But when invoked thru .NET it gives error msg "SafeArrayTypeMisMatchException Specified Array was not of expected type"... My head is getting sore from too much debugging... can any one shed some light on this... .NET Code ======= UserMgmt p; object Accesslist; object ErrorMsg; p = new UserMgmt(); p.GetUserAccessControlList ( "1",2,"3",out Accesslist,out ErrorMsg); VC++ IDL File ========= interface IUsrMgmt : IDispatch { [id(305), helpstring("method GetUserAccessControlList")] HRESULT GetUserAccessControlList([in] BSTR bstrPartyBranchCode, [in] long nDealerID, [in] BSTR bstrTerminalMACAddr, [out] VARIANT *pvarAccessList, [out] VARIANT *pvarErrMsg); };
VC++ Code ======= STDMETHODIMP CAdmin::GetUserAccessControlList (BSTR bstrPartyBranchCode, long nDealerID, BSTR bstrTerminalMACAddr, VARIANT *pvarAccessList, VARIANT *pvarErrMsg) { VARIANT lvarPartyBranchCode, lvarDealerID, lvarMACAddress; _ParameterPtr lpcParamPartyBranchCode = 0, lpcParamDealerID = 0, lpcParamMACAddress = 0, lpcParamErrMsg = 0; _ConnectionPtr lObjConnection (__uuidof(Connection)); _RecordsetPtr lObjAccessList (__uuidof(Recordset)); _CommandPtr lObjCommand (__uuidof(Command)); char lpPartyBranchCode [ACCESSLIST_PARTYBRANCHCODE_LEN + 1], lpMACAddress [ACCESSLIST_MACADDRESS_LEN + 1], lpErrMsg [MAX_ERR_MSG_LEN]; MessageHeader lstMsgHeader; tagUserAccessControlList lstUserACL; vector <tagUserAccessControlList> lvecUserACL; vector <tagUserAccessControlList>::iterator lvecUserACLItor; time_t lnMsgSendTime; int lnAccessListCnt = 0, lnRowCnt = 0; long lnAllowed; VariantInit (pvarAccessList); VariantInit (pvarErrMsg); lvarPartyBranchCode.vt = VT_BSTR; lvarDealerID.vt = VT_I4; lvarMACAddress.vt = VT_BSTR; pvarErrMsg->vt = VT_BSTR; pvarErrMsg->bstrVal = ::SysAllocString (L""); <file://Validate> file://Validate Party Branch Code if (IsBadReadPtr (bstrPartyBranchCode, sizeof (BSTR))) { strcpy (lpErrMsg, ERR_ACCESSLIST_INVALID_PARTYBRANCHCODE); convertFromStringToBSTR (lpErrMsg, pvarErrMsg->bstrVal); return S_FALSE; } else { convertFromBSTRToString (bstrPartyBranchCode, lpPartyBranchCode); convertFromStringToBSTR (lpPartyBranchCode, lvarPartyBranchCode.bstrVal); } <file://Party> file://Party Branch Code should not be empty if (strcmp (lpPartyBranchCode, EMPTY_STRING) == 0) { strcpy (lpErrMsg, ERR_ACCESSLIST_BLANK_PARTYBRANCHCODE); convertFromStringToBSTR (lpErrMsg, pvarErrMsg->bstrVal); return S_FALSE; } <file://Validate> file://Validate Terminal MAC Address if (IsBadReadPtr (bstrTerminalMACAddr, sizeof (BSTR))) { strcpy (lpErrMsg, ERR_ACCESSLIST_INVALID_MACADDRESS); convertFromStringToBSTR (lpErrMsg, pvarErrMsg->bstrVal); return S_FALSE; } else { convertFromBSTRToString (bstrTerminalMACAddr, lpMACAddress); convertFromStringToBSTR (lpMACAddress, lvarMACAddress.bstrVal); } <file://Terminal> file://Terminal MAC Address should not be empty if (strcmp (lpMACAddress, EMPTY_STRING) == 0) { strcpy (lpErrMsg, ERR_ACCESSLIST_BLANK_MACADDRESS); convertFromStringToBSTR (lpErrMsg, pvarErrMsg->bstrVal); return S_FALSE; } <file://DealerID> file://DealerID lvarDealerID.vt = VT_I4; lvarDealerID.lVal = nDealerID; try { GetRegStr(HKEY_LOCAL_MACHINE,"SOFTWARE\\MME\\ADMIN\\DB","ConnStr", m_szConnStr); if ( strcmp (m_szConnStr ,"") == 0 ) <file://---> file://--- DB ConnStr is empty { LogError ("DB Connection String Empty/Not Found In Registry Key {HKEY_LOCAL_MACHINE\\SOFTWARE\\MME\\Forex\\DB\\ConnStr} [MMEAdmin::Activate () Failed] ",gszErrorLogPath); return S_FALSE; } <file://strcpy> file://strcpy(m_szConnStr, "driver={SQL Server}; server=Tandem; uid=sa; pwd=; database=mme"); lObjConnection->Open (m_szConnStr, "", "", adConnectUnspecified); lObjCommand->ActiveConnection = lObjConnection; lObjCommand->CommandText = "stp_GetUserAccessControlList"; <file://Set> file://Set 1st parameter : @sPartyBranchCode lpcParamPartyBranchCode = lObjCommand->CreateParameter ("P_PartyBranchCode", adVarChar, adParamInput, ACCESSLIST_PARTYBRANCHCODE_LEN, lvarPartyBranchCode); lObjCommand->Parameters->Append (lpcParamPartyBranchCode); <file://Set> file://Set 2nd parameter : @nDealerID lpcParamDealerID = lObjCommand->CreateParameter ("P_DealerID", adInteger, adParamInput, sizeof (long), lvarDealerID); lObjCommand->Parameters->Append (lpcParamDealerID); <file://Set> file://Set 3rd parameter : @sTerminalMACAddr lpcParamMACAddress = lObjCommand->CreateParameter ("P_TerminalMACAddr", adVarChar, adParamInput, ACCESSLIST_MACADDRESS_LEN, lvarMACAddress); lObjCommand->Parameters->Append (lpcParamMACAddress); <file://Set> file://Set 4th parameter : @sErrMsg lpcParamErrMsg = lObjCommand->CreateParameter ("P_ErrMsg", adVarChar, adParamOutput, ACCESSLIST_ERRMSG_LEN); lObjCommand->Parameters->Append (lpcParamErrMsg); lObjAccessList = lObjCommand->Execute (NULL, NULL, adCmdStoredProc); if (!lObjAccessList->BOF) { while (!lObjAccessList->adoEOF) { <file://nMsgCode> file://nMsgCode lstUserACL.nMessageCode = lObjAccessList->GetCollect(ACCESSLIST_NMSGCODE_COLNAME); <file://bAllowed> file://bAllowed lnAllowed = lObjAccessList->GetCollect(ACCESSLIST_BALLOWED_COLNAME); if (lnAllowed == 1) { lstUserACL.bAllowed = TRUE; } else if (lnAllowed == 0) { lstUserACL.bAllowed = FALSE; } lvecUserACL.push_back (lstUserACL); lObjAccessList->MoveNext (); } lnAccessListCnt = lvecUserACL.size (); <file://Message> file://Message Header Information time (&lnMsgSendTime); lstMsgHeader.msgLength = sizeof (MessageHeader) + (lnAccessListCnt * sizeof (tagUserAccessControlList)); lstMsgHeader.msgSendTime = lnMsgSendTime; strcpy (lstMsgHeader.sourceBranchId, lpPartyBranchCode); lstMsgHeader.sourceTerminalId = 0; lstMsgHeader.sourceUserId = 0; lstMsgHeader.transactionCode = MSG_USERACCESSCONTROLLIST_RESPONSE; SAFEARRAY* lpSafeByteArray; BYTE* lpData; lpSafeByteArray = SafeArrayCreateVector (VT_UI1, 0, sizeof (MessageHeader) + (lnAccessListCnt * sizeof (tagUserAccessControlList))); SafeArrayAccessData (lpSafeByteArray, (void**) &lpData); <file://Copy> file://Copy header and body seperately CopyMemory (&lpData[0], (void *) &lstMsgHeader, sizeof (MessageHeader)); for (lnRowCnt = 0, lvecUserACLItor = lvecUserACL.begin (); lvecUserACLItor != lvecUserACL.end (); ++lnRowCnt, ++lvecUserACLItor) { CopyMemory (&lpData[sizeof (MessageHeader) + (lnRowCnt * sizeof (tagUserAccessControlList))], (void *) lvecUserACLItor, sizeof (tagUserAccessControlList)); } SafeArrayUnaccessData (lpSafeByteArray); VariantInit (pvarAccessList); pvarAccessList->vt = VT_UI1 | VT_ARRAY; pvarAccessList->parray = lpSafeByteArray; lObjAccessList->Close(); lObjConnection->Close (); } } catch (_com_error &ObjErr) { GetComError (ObjErr, lpErrMsg); convertFromStringToBSTR (lpErrMsg, pvarErrMsg->bstrVal); return S_FALSE; } return S_OK; } Regards Yogesh Shetty Team COE Financial Technologies (India) Ltd. URL: <http://www.ftindia.com> www.ftindia.com mailto : <mailto:[EMAIL PROTECTED]> [EMAIL PROTECTED] contact : +91 22 6164145 You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.