0

com 相互運用機能を介して、配列を 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);        
    }  
}

これがアイドル

[id(23)] void GetArrayVar(VARIANT arr);

問題は、メッセージ ボックスに文字列の最初の文字、つまり「O」しか表示されないことです。「T」、「F」。文字列全体を読みたい。助言がありますか ?

4

4 に答える 4

0

これは、Unicode/UTF8 文字列を送信しているが、メッセージ ボックスは ANSI C 文字列を想定しているという事実に基づいています。送信する前に文字列を ASCII に変換してみてください。ここで Encoding クラスを見てください http://msdn.microsoft.com/en-us/library/system.text.encoding.aspx

それらをバイト配列として送信したい場合があります。

var bytes = Encoding.ASCII.GetBytes("one");
于 2013-03-19T11:58:14.293 に答える
0

確かではありませんが、Unicode/MBCS の不一致があるようです。

マネージ部分は UTF-16 でエンコードされた文字列の配列を作成しますが、アンマネージ部分はマルチバイト文字セットでコンパイルされているようです。したがって、最初のヌル文字 (実際には UTF-16 文字の 2 番目のバイト) を確認すると、MBCS コードは文字列の末尾に到達したと見なします。

1 つの解決策は、C++ プロジェクトの文字セット設定を Unicode に変更して再構築することです。

もう 1 つは、コードを変更することです。

...
LPCWSTR * arrayAccess = NULL; // change LPCSTR -> LPCWSTR
...

for(int iIndex = lStartBound; iIndex <= lEndBound; iIndex ++)
{   
    bstr_t myString = arrayAccess[iIndex];
    AfxMessageBox(myString);        
} 

bstr_tBSTR で正しく初期化されますが、変換も提供されるconst char*ため、AfxMessageBox への呼び出しは問題ありません。

于 2013-03-19T14:13:32.820 に答える
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);
}
于 2013-03-19T12:34:53.200 に答える
0

VARIANT の代わりに SAFEARRAY を渡す必要があります。

[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();
}
于 2013-03-19T12:16:47.853 に答える