我尝试通过com interop将数组从c#发送到c ++。
这是c#Code
public void SendArraytoCPlusPlus()
{
GGXForVBA.GeoAtlas GA = new GGXForVBA.GeoAtlas();
string[] arr = new string[3];
arr[0] = "One";
arr[1] = "Two";
arr[2] = "Five";
GA.GetArrayVar(arr);
}
这是c ++代码
void GeoAtlas::GetArrayVar(VARIANT& arr)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
SAFEARRAY* pSafeArray = arr.parray;
long lStartBound = 0;
long lEndBound = 0;
SafeArrayGetLBound(pSafeArray,1,&lStartBound);
SafeArrayGetUBound(pSafeArray,1,&lEndBound);
LPCSTR * arrayAccess = NULL;
SafeArrayAccessData( pSafeArray , (void**)&arrayAccess);
for(int iIndex = lStartBound; iIndex <= lEndBound; iIndex ++)
{
LPCTSTR myString = (LPCTSTR)arrayAccess[iIndex];
AfxMessageBox(myString);
}
}
这是idl
[id(23)] void GetArrayVar(VARIANT arr);
问题是,消息框只显示字符串的第一个字母,即“O”。 'T','F'。我想读整个字符串。有什么建议吗?
答案 0 :(得分:0)
这是基于您发送Unicode / UTF8字符串但消息框需要ANSI C字符串的事实。尝试在发送之前将字符串转换为ASCII。在这里查看编码类http://msdn.microsoft.com/en-us/library/system.text.encoding.aspx
您可能希望尝试将它们作为字节数组发送。
var bytes = Encoding.ASCII.GetBytes("one");
答案 1 :(得分:0)
您应该传递SAFEARRAY而不是VARIANT:
[id(23)] void GetArrayVar([in] SAFEARRAY(BSTR) arr);
在实施中,像这样访问它:
void GeoAtlas::GetArrayVar(SAFEARRAY* arr)
{
CComSafeArray<BSTR> sa;
sa.Attach(arr);
for (int i = sa.GetLowerBound(); i <= sa.GetUpperBound(); ++i)
{
AfxMessageBox(sa[i]);
}
sa.Detach();
}
答案 2 :(得分:0)
发送方看起来很好。在接收方试试这个。
[id(1), helpstring("method SetArrayVar")] HRESULT SetArrayVar([in] VARIANT varMachineList);
STDMETHODIMP GeoAtlas::SetArrayVar(VARIANT arr)
{
long lower, upper;
SafeArrayGetLBound(pSafeArray, 1, &lower);
SafeArrayGetUBound(pSafeArray, 1, &upper);
DWORD dwItems = upper - lower + 1;
resize(dwItems);
SAFEARRAY* pSafeArray = arr.parray;
BSTR* pBstr;
if ( SUCCEEDED(SafeArrayAccessData(pSafeArray, (LPVOID*) &pBstr)) )
{
iterator it = begin();
for ( long i=lower; i<=upper; i++, pBstr++, it++ )
{
USES_CONVERSION;
*it = OLE2CT(*pBstr);
// Here you gets array elements and use it
}
}
// release the data block
SafeArrayUnaccessData(pSafeArray);
}
答案 3 :(得分:0)
不确定,但看起来你有Unicode / MBCS不匹配。
托管部分创建一个UTF-16编码字符串数组,而非托管部分似乎是使用多字节字符集编译的。因此,在看到第一个空字符(实际上只是UTF-16字符的第二个字节)时,您的MBCS代码认为它已到达字符串的末尾。
一种解决方案是将C ++项目中的字符集设置更改为Unicode并重建。
另一个是改变代码:
...
LPCWSTR * arrayAccess = NULL; // change LPCSTR -> LPCWSTR
...
for(int iIndex = lStartBound; iIndex <= lEndBound; iIndex ++)
{
bstr_t myString = arrayAccess[iIndex];
AfxMessageBox(myString);
}
bstr_t
将使用BSTR正确初始化,但它也提供转换为const char*
,因此调用AfxMessageBox即可。