動作環境
Visual C++ (Visual Studio 2005)
VB6.0 SP5
WinXp
C++でCOMを作成しました。
それをVBから呼び出し文字列もしくは数値を受け取りたいのですが
どうしても文字列が空で参照できません。
C++側
-------------------------------------------------------------------------------------------------
宣言部分
[id(5), helpstring("メソッド get_test")] HRESULT get_test([in] BSTR str, [out] BSTR* strout);
処理部分
STDMETHODIMP Caaa::get_test(BSTR str, BSTR* strout)
{
CComBSTR testBstr("あいうえお");
BSTR bstr = testBstr; // bstrにはあいうえおが格納されている
CAtlString aaa;
aaa = (WCHAR*)str;
MessageBox(NULL,spBstr,aaa,0); // あいうえおが表示される
MessageBox(NULL,bstr,aaa,0); // あいうえおが表示される
strout = &bstr; // out引数に"あいうえお"のアドレス格納
// これがVB側で参照できればいい。
return S_OK;
}
vb側
-------------------------------------------------------------------------------------------------
Private Sub Command3_Click()
On Error GoTo Err_Command3_Click
Dim fff As aaa
Dim str1 As String
Dim str2 As String
str1 = "わたった" ' この文字がC++に渡っているのは確認済
Set fff = CreateObject("ttt.aaa.1")
fff.get_test str1, str2 'C++メソッド実行
MsgBox (str2) ' str2が空になっており参照できない
Set fff = Nothing
Exit Sub
End Sub
この方法でVB側に"あいうえお"の文字が渡ってこないのはなぜでしょうか?
色々と試しているのですが、str2は参照渡しで渡ってこないのでしょうか?
それとも根本的に何か間違っているのか、よくわからない状態になってしまいました。
助言いただけたら幸いです。
宜しくお願いします。
とりあえず、C++での基本中の基本なところが出来てないような。
>strout = &bstr;
*strout = bstr;
int test(int a){ a = 10; }
int main()
{
int a;
test(a);
}
でaに10が設定されないのと同じ理由。
返信ありがとうございました。
strout = &bstr;
の後*stroutを参照すると"あいうえお"が入っているので同じことだとは思っていたのですが。。。
ご指摘どおりのロジックにしたところ、
もちろん*stroutには値がはいるのですが、vbに返ってきたところで"あいうえお"を見ることが出来ないのです。
値の返し方がまずいのか何なのかもはやわからなくなってしまいました。。
となると
おそらく
>CComBSTR
を使っているからです。
CComBSTRは内部で SysAllocString,SysFreeStringを呼んでいますので、
>fff.get_test str1, str2 'C++メソッド実行
get_testを抜けると自動的にSysFreeStringがよばれ、設定した文字列が解放されてしまうのではないでしょうか。
ですので、
>*strout = bstr;
というようにCComBSTRの値を使わないで、SysAllocStringした値を渡しましょう。
*strout = SysAllocString( bstr );
# *strout = bstr.Copy(); でもいけるかもしれないけど。
訂正)
># *strout = bstr.Copy(); でもいけるかもしれないけど。
# *strout = testBstr.Copy(); でもいけるかもしれないけど。
追記)
stroutにもともとある文字列をSysFreeStringしないとまずい気がします。
SysFreeString( *strout );
DLLの例ですが、過去ログも参考にしてください。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200606/06060060.txt
の Sample03W
何度もすみません。
>VB6.0 SP5
だと、SysAllocStringじゃまずい気がしてきました。
SysAllocStringByteLenでBSTR型のマルチバイト文字の領域を渡さないと。
つまり Sample03A のような記述の仕方でないとダメなような。
(入力は、char*ですので注意してください)
*strout = SysAllocString(testBstr);
で値がVBで見れました!!
ほんとうに助かりました!!
もっと勉強せねばならないと改めて思いました。
ありがとうございました。
>*strout = SysAllocString(testBstr);
あら。COMならそれでいけるんですな。
変な文字列になっていなければ大丈夫だと思います。
忘れ物
つ[解決チェック]
何から何まですみません。。。
今回初めて利用しましたがとても勉強になりました。
ツイート | ![]() |