[英]Sending an Array of strings from c# to c++ via COM
I tried to send an array from c# to c++ via com interop. 我试图通过com interop将数组从c#发送到c ++。
Here is the c# Code 这是c#代码
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);
}
Here is the c++ code 这是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);
}
}
This is the idl 这是idl
[id(23)] void GetArrayVar(VARIANT arr);
The problem is, The message box only shows the FIRST letters of the strings, ie ''O'. 问题是,消息框仅显示字符串的第一个字母,即“ O”。 'T', 'F' .
'T','F'。 I want to read the whole string.
我想阅读整个字符串。 Any suggestions ?
有什么建议么 ?
This is based on the fact that you're sending an Unicode/UTF8 string but the message box expects an ANSI C string. 这是基于以下事实:您正在发送Unicode / UTF8字符串,但消息框需要ANSI C字符串。 Try to convert the strings to ASCII before sending them.
发送之前,请尝试将字符串转换为ASCII。 Look at the Encoding class here http://msdn.microsoft.com/en-us/library/system.text.encoding.aspx
在此处查看Encoding类http://msdn.microsoft.com/zh-cn/library/system.text.encoding.aspx
You may want to try to send them as byte array. 您可能想尝试将它们作为字节数组发送。
var bytes = Encoding.ASCII.GetBytes("one");
You should pass a SAFEARRAY instead of a VARIANT: 您应该传递SAFEARRAY而不是VARIANT:
[id(23)] void GetArrayVar([in] SAFEARRAY(BSTR) arr);
And in the implementation, access it like this: 在实现中,像这样访问它:
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();
}
Sending side looks fine. 发送方看起来不错。 On receiving side try this.
在接收端尝试此操作。
[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);
}
Not sure, but looks like you have Unicode/MBCS mismatch. 不确定,但看起来您的Unicode / MBCS不匹配。
The managed part creates an array of UTF-16 encoded strings, while it seems that the unmanaged part is compiled with multibyte charset. 托管部分创建了一个由UTF-16编码的字符串数组,而非托管部分似乎是使用多字节字符集进行编译的。 Therefore, upon seeing first null character (which is actually just the second byte of UTF-16 character) your MBCS code thinks it has reached the end of the string.
因此,一旦看到第一个空字符(实际上只是UTF-16字符的第二个字节),您的MBCS代码就会认为它已到达字符串的末尾。
One solution is to change the character set setting in your C++ project to Unicode and rebuild. 一种解决方案是将C ++项目中的字符集设置更改为Unicode并重新生成。
Another one is to change the code: 另一个是更改代码:
...
LPCWSTR * arrayAccess = NULL; // change LPCSTR -> LPCWSTR
...
for(int iIndex = lStartBound; iIndex <= lEndBound; iIndex ++)
{
bstr_t myString = arrayAccess[iIndex];
AfxMessageBox(myString);
}
bstr_t
will be correctly initialized with BSTR, but it also provides conversion to const char*
so call to AfxMessageBox will be OK. bstr_t
将使用BSTR正确初始化,但是它也提供了到const char*
转换,因此可以正常调用AfxMessageBox。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.