簡體   English   中英

通過COM將字符串數組從c#發送到c ++

[英]Sending an Array of strings from c# to c++ via COM

我試圖通過com interop將數組從c#發送到c ++。

這是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);
}

這是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'。 我想閱讀整個字符串。 有什么建議么 ?

這是基於以下事實:您正在發送Unicode / UTF8字符串,但消息框需要ANSI C字符串。 發送之前,請嘗試將字符串轉換為ASCII。 在此處查看Encoding類http://msdn.microsoft.com/zh-cn/library/system.text.encoding.aspx

您可能想嘗試將它們作為字節數組發送。

var bytes = Encoding.ASCII.GetBytes("one");

您應該傳遞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();
}

發送方看起來不錯。 在接收端嘗試此操作。

[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);
}

不確定,但看起來您的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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM