Transferring arrays from C++ library to C# application
-
Hi, I'm having trouble in transferring arrays of short integers from C++ library to C# application. I got the sources of a library, written in C++, that defines interface in IDL file. The original methods transfer "basic" objects, such as BOOL and BSTR. I need to add a new method to the interface for transferring two arrays of short integers. For that purpose, I create two safe arrays and populate them with the numbers. However, when I try to invoke the C# method I get TypeMismatch error code (when I pass only the string objects, it works OK). The C++ code includes the following definition in IDL file: library CodecLib { ... dispinterface _ILiveEvents { properties: methods: ... [id(4), helpstring("method DataReady")] HRESULT DataReady([in] BSTR strForward, [in] SAFEARRAY(short) FwdBuffer, [in] BSTR strReturn, [in] SAFEARRAY(short) RetBuffer); }; ... }; The following C# code implements the interface defined in the IDL file: private void DataReady(string sForward, Array ForwardData, string sRetrun, Array ReturnData) { ... } The following C++ code prepares the data in the safe arrays: void CLive::DataReady(short *pFwdBuf, short *pRetBuf, int nBufferSize) { long lIndex; SAFEARRAYBOUND ArrayBound[2]; ArrayBound[0].cElements = nBufferSize; ArrayBound[0].lLbound = 0; ArrayBound[1].cElements = nBufferSize; ArrayBound[1].lLbound = 0; m_pFwdBuffer = SafeArrayCreate(VT_I2, 1, &ArrayBound[0]); m_pRetBuffer = SafeArrayCreate(VT_I2, 1, &ArrayBound[1]); // Set data in safe arrays for (lIndex=0; lIndex<nBufferSize; lIndex++) { SafeArrayPutElement(m_pFwdBuffer, &lIndex, &pFwdBuf[lIndex]); SafeArrayPutElement(m_pRetBuffer, &lIndex, &pRetBuf[lIndex]); } // Send data to clients Fire_DataReady(m_strForward, m_pFwdBuffer, m_strReturn, m_pRetBuffer); // Release safe arrays SafeArrayDestroy(m_pFwdBuffer); SafeArrayDestroy(m_pRetBuffer); m_pFwdBuffer = NULL; m_pRetBuffer = NULL; } The following C++ code distributes the data to the clients. However, calling Invoke() returns TypeMismatch error, with uArgErr equals to 3: HRESULT Fire_DataReady(BSTR strForward, SAFEARRAY *pFwdBuf, BSTR strReturn, SAFEARRAY *pRetBuf) { HRESULT hr = S_OK; T * pThis = static_cast<T *>(this); int cConnections = m_vec.GetSize(); for (int iConnection = 0; iConnection < cConnections; iConnection++) { pThis->Lock(); CComPtr<IUnknown> punkConnection = m_vec.Get
-
Hi, I'm having trouble in transferring arrays of short integers from C++ library to C# application. I got the sources of a library, written in C++, that defines interface in IDL file. The original methods transfer "basic" objects, such as BOOL and BSTR. I need to add a new method to the interface for transferring two arrays of short integers. For that purpose, I create two safe arrays and populate them with the numbers. However, when I try to invoke the C# method I get TypeMismatch error code (when I pass only the string objects, it works OK). The C++ code includes the following definition in IDL file: library CodecLib { ... dispinterface _ILiveEvents { properties: methods: ... [id(4), helpstring("method DataReady")] HRESULT DataReady([in] BSTR strForward, [in] SAFEARRAY(short) FwdBuffer, [in] BSTR strReturn, [in] SAFEARRAY(short) RetBuffer); }; ... }; The following C# code implements the interface defined in the IDL file: private void DataReady(string sForward, Array ForwardData, string sRetrun, Array ReturnData) { ... } The following C++ code prepares the data in the safe arrays: void CLive::DataReady(short *pFwdBuf, short *pRetBuf, int nBufferSize) { long lIndex; SAFEARRAYBOUND ArrayBound[2]; ArrayBound[0].cElements = nBufferSize; ArrayBound[0].lLbound = 0; ArrayBound[1].cElements = nBufferSize; ArrayBound[1].lLbound = 0; m_pFwdBuffer = SafeArrayCreate(VT_I2, 1, &ArrayBound[0]); m_pRetBuffer = SafeArrayCreate(VT_I2, 1, &ArrayBound[1]); // Set data in safe arrays for (lIndex=0; lIndex<nBufferSize; lIndex++) { SafeArrayPutElement(m_pFwdBuffer, &lIndex, &pFwdBuf[lIndex]); SafeArrayPutElement(m_pRetBuffer, &lIndex, &pRetBuf[lIndex]); } // Send data to clients Fire_DataReady(m_strForward, m_pFwdBuffer, m_strReturn, m_pRetBuffer); // Release safe arrays SafeArrayDestroy(m_pFwdBuffer); SafeArrayDestroy(m_pRetBuffer); m_pFwdBuffer = NULL; m_pRetBuffer = NULL; } The following C++ code distributes the data to the clients. However, calling Invoke() returns TypeMismatch error, with uArgErr equals to 3: HRESULT Fire_DataReady(BSTR strForward, SAFEARRAY *pFwdBuf, BSTR strReturn, SAFEARRAY *pRetBuf) { HRESULT hr = S_OK; T * pThis = static_cast<T *>(this); int cConnections = m_vec.GetSize(); for (int iConnection = 0; iConnection < cConnections; iConnection++) { pThis->Lock(); CComPtr<IUnknown> punkConnection = m_vec.Get