COMの引数に文字列の配列 – プログラミング – Home

COMの引数に文字列の配列
 
通知
すべてクリア

[解決済] COMの引数に文字列の配列


たけ
 たけ
(@たけ)
ゲスト
結合: 24年前
投稿: 116
Topic starter  

C#で作成したライブラリをCOMとして呼び出しています。

C#側は、戻り値をstringの配列で返します。
public string[] GetStr()
{
}

自動で作成されたカスタムインターフェイスの定義上は、

virtual HRESULT __stdcall GetStr (
SAFEARRAY * * pRetVal ) = 0;

となっています。

VC++6.0側で、

CComBSTR out[4];
pClass1->GetSql((struct tagSAFEARRAY **)&out);

とコールしたところ
例外処理 (初回) は ComTest.exe (KERNEL32.DLL) にあります: 0xE06D7363: Microsoft
C++ Exception。

となってしまいました。
キャストの仕方がおかしいでしょうか。


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

SafeArrayをほしがっているところに無理やりCComBSTR型を渡してもダメなんじゃないか
な。

SAFEARRAY型を用意して、いちいち代入してあげないとイケなそう。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

試しにやってみた。(ただしCOMを使っているわけではない)

#include <comdef.h>
#include <cstdlib>
#include <iostream>
#include <atlbase.h>

// 実験用関数
void test( LPSAFEARRAY* ppsa )
{
SAFEARRAY*& psa = *ppsa;
long lb, ub;

::SafeArrayGetLBound( psa, 1, &lb );
::SafeArrayGetUBound( psa, 1, &ub );

::SafeArrayLock( psa );

for ( long i = lb; i <= ub; i++ )
{
BSTR wcs;
::SafeArrayGetElement( psa, &i, ( void* )&wcs );
std::wcout << wcs << std::endl;
}

::SafeArrayUnlock( psa );
}

int main()
{
std::wcout.imbue( std::locale( japanese ) );

CComBSTR bs[ 4 ] = { Lあんぱん, L食パン, Lカレーパン, LABC };

SAFEARRAY* psa;
SAFEARRAYBOUND sab;
sab.cElements = 4;
sab.lLbound = 0;
psa = ::SafeArrayCreate( VT_BSTR, 1, &sab );
BSTR* data;
::SafeArrayAccessData( psa, ( void** )&data );
for ( long i = 0; i < 4; i++ )
{
data[ i ] = bs[ i ];
}
::SafeArrayUnaccessData( psa );

test( &psa );

::SafeArrayDestroy( psa );

return 0;
}


返信引用
たけ
 たけ
(@たけ)
ゲスト
結合: 24年前
投稿: 116
Topic starter  

Blueさん、お試しありがとうございます。

Blueさんのご意見を参考に
SAFEARRAYと格闘していて遅くなりました。

ちなみに↓を参考にしてみました。
http://www.orin.jp/dev/tutorial_rao.html

以下ソースで配列で結果を受け取ることができました。

SAFEARRAY* pSa;
SAFEARRAYBOUND bound = { 3 ,0 };
pSa = SafeArrayCreate( VT_BSTR , 1, &bound );
CComBSTR* iArray;

result = m_pClass1->GetStr(&pSa);

SafeArrayAccessData( pSa, (void**)&iArray); // iArrayに戻り値が入っているのを確認。

SafeArrayUnaccessData( pSa );
SafeArrayDestroy( pSa );

う~ん。Blueさんの方が30分以上前に出来てる~。
SAFEARRAYなんて初めて触りました。勉強になりました。ありがとうございます。


返信引用
たけ
 たけ
(@たけ)
ゲスト
結合: 24年前
投稿: 116
Topic starter  

解決時チェックを忘れました。チェックします。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

あら。
値を設定したのを渡すのでなくて、値を設定してもらってから取得するのですね。

ちなみに、SafeArrayのラッパークラスがMFCにあります。(COleSafeArray)
VC6より新しい環境であれば、CComSafeArrayってのがあるらしいですが。
(CComBSTRやCComVariantほど重宝するものではないかなと。)


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました