C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[12]: BTSTR の受け渡し方法について


(過去ログ 16 を表示中)

[トピック内 13 記事 (1 - 13 表示)]  << 0 >>

■5860 / inTopicNo.1)  BTSTR の受け渡し方法について
  
□投稿者/ siroisi (1回)-(2007/07/25(Wed) 00:13:18)

分類:[.NET 全般] 


VC6++からCOMを使用して、C#のDLLの関数に
結果格納用の変数(BTSTR型)を引数に渡して、やり取りしたいのですが
コンパイルすらとおりません。
関数の型は以下の通りです。

UINT GetVersion(BTSTR *Version);

当方としては、bstr_tで変数を作り、
引数に渡せばよいのかと思い
以下のように、色々試してはみたのですが、
コンパイルエラーが発生してしまいました。

bstr_t bVer

pp->GetVersion(bVer);
pp->GetVersion(*bVer);
pp->GetVersion(&bVer);

BTSTRの受け渡しはどのように行うべきなのでしょうか。
尚、本実行ファイルはCで作っているのですが
受け取ったBTSTRをchar型の変数に変換することも可能なのでしょうか
分かる方がおりましたら御教授をよろしくお願い致します。
引用返信 編集キー/
■5862 / inTopicNo.2)  Re[1]: BTSTR の受け渡し方法について
□投稿者/ Blue (323回)-(2007/07/25(Wed) 00:37:47)
BSTR*なら_bstr_tクラスを使わずとも、単にBSTRの変数でよいのでは?

BSTR bVer;

pp->GetVersion(&bVer);

BSTR*はC#側で領域確保されるという意味ですよね?
そしたら解放関数(SysFreeString等)の呼び出しが必要になるかも。
# BSTRの文字列を渡すのであれば、C側でSysAllocStringやらで取得した
# 値を指定することになるのですけど。


>受け取ったBTSTRをchar型の変数に変換することも可能なのでしょうか
可能です。
Cとなると、WideCharToMultiByteあたりのAPIか
wcstombs関数を使うことになるでしょう。

C++ならBSTRを_bstr_tにアッタチすればconst char*のキャストができるので
strcpyやらsprintfで簡単に取得できます。
引用返信 編集キー/
■5863 / inTopicNo.3)  Re[2]: BTSTR の受け渡し方法について
□投稿者/ siroisi (2回)-(2007/07/25(Wed) 00:57:35)
No5862 (Blue さん) に返信

御回答有難うございます。

> BSTR*なら_bstr_tクラスを使わずとも、単にBSTRの変数でよいのでは?
>
> BSTR bVer;
>
> pp->GetVersion(&bVer);
CでもBSTR型の変数の宣言は可能なんでしょうか?

> BSTR*はC#側で領域確保されるという意味ですよね?
> そしたら解放関数(SysFreeString等)の呼び出しが必要になるかも。
その通りです。領域の開放については調べてみます。

> >受け取ったBTSTRをchar型の変数に変換することも可能なのでしょうか
> 可能です。
> Cとなると、WideCharToMultiByteあたりのAPIか
> wcstombs関数を使うことになるでしょう。
Cで作成しているので、ご回答の関数を試してみます。

CでもBSTR型の変数の宣言をするのに、特別にインクルードするヘッダ等は必要でしょうか
よろしくお願い致します。

引用返信 編集キー/
■5865 / inTopicNo.4)  Re[3]: BTSTR の受け渡し方法について
□投稿者/ Blue (324回)-(2007/07/25(Wed) 01:20:22)
>CでもBSTR型の変数の宣言は可能なんでしょうか?
可能でしょう。

wtypes.hに

typedef OLECHAR* BSTR;

のような型宣言があります。
(wtypes.hはwindows.hをインクルードすれば取り込まれるようです。)
引用返信 編集キー/
■5867 / inTopicNo.5)  Re[4]: BTSTR の受け渡し方法について
□投稿者/ siroisi (4回)-(2007/07/25(Wed) 07:12:48)
No5865 (Blue さん) に返信
> >CでもBSTR型の変数の宣言は可能なんでしょうか?
> 可能でしょう。
>
> wtypes.hに
>
> typedef OLECHAR* BSTR;
>
> のような型宣言があります。
> (wtypes.hはwindows.hをインクルードすれば取り込まれるようです。)

これから、試してみます。
有難うございました
引用返信 編集キー/
■5868 / inTopicNo.6)  Re[5]: BTSTR の受け渡し方法について
□投稿者/ Blue (325回)-(2007/07/25(Wed) 08:30:41)
ちなみに本題と関係ないですが、C言語でCOMを扱うのは結構な手間になると思います。
個人的にはこちらのほうが難易度が高いと思われるのですけどね。
引用返信 編集キー/
■5908 / inTopicNo.7)  Re[6]: BTSTR の受け渡し方法について
□投稿者/ siroisi (5回)-(2007/07/25(Wed) 21:24:34)
No5868 (Blue さん) に返信
> ちなみに本題と関係ないですが、C言語でCOMを扱うのは結構な手間になると思います。
> 個人的にはこちらのほうが難易度が高いと思われるのですけどね。
他の人からの引継ぎ作業のために仕方がなくやっております。

アドバイス通りにBSTR型の変数を作成し、そのアドレスを渡すことができました。

BSTR bVer;
pp->GetVersion(&bVer);

この後、char型の配列にbVerに格納されているバージョン情報を
コピーするために以下の通り行ったのですが、領域破壊等の不安があります。

char Cversion[128];
char getVer[256];
_bstr_t bVersion(Cversion);

bVersion = bVer; //@ _bstr_t型の変数に値を移す

sprintf(getVer, '\0', (const char *)bVersion); //A const charでキャストし、char型の文字配列に格納

デバッグ等でも確認しましたが、値は正常に文字列としてgetVerに格納されておりました。
ただ気になるのは、@、Aの処理でオーバーフロー等が発生する可能性があるのではないかということ
もしくは、事前にBSTR型や_bstr_t型の変数のサイズにより、サイズを超えていたら、格納しない
という方法はあるのでしょうか?(※strlen()関数のような)

昨日から、ご迷惑をおかけしておりますが、御助力をお願い致します。













引用返信 編集キー/
■5909 / inTopicNo.8)  Re[7]: BTSTR の受け渡し方法について
□投稿者/ Blue (326回)-(2007/07/25(Wed) 23:22:42)
結局 _bstr_t"クラス"を使うことにしたんでしょうか?
_bstr_tクラスは内部で自動的にメモリを割り当てるのでメモリ不足になるようなことはないと思われます。

2のほうは_bstr_tクラスのメソッドにサイズが取得できるものがあります。(ただしUnicodeでの文字数)
固定長配列が不安であれば動的にmallocやらnewやらやればいいです。
(std::stringを使えば同様にメモリを内部で扱うためメモリ不足になるとかはない)
引用返信 編集キー/
■5913 / inTopicNo.9)  Re[8]: BTSTR の受け渡し方法について
□投稿者/ siroisi (6回)-(2007/07/25(Wed) 23:59:51)
No5909 (Blue さん) に返信
> 結局 _bstr_t"クラス"を使うことにしたんでしょうか?
> _bstr_tクラスは内部で自動的にメモリを割り当てるのでメモリ不足になるようなことはないと思われます。
>
> 2のほうは_bstr_tクラスのメソッドにサイズが取得できるものがあります。(ただしUnicodeでの文字数)
> 固定長配列が不安であれば動的にmallocやらnewやらやればいいです。
> (std::stringを使えば同様にメモリを内部で扱うためメモリ不足になるとかはない)

御回答ありがとうございます。

> 固定長配列が不安であれば動的にmallocやらnewやらやればいいです。
> (std::stringを使えば同様にメモリを内部で扱うためメモリ不足になるとかはない)

元データが固定長(128byte以下、常に固定長)で保障されているような場合
自分のコーディング(sprintf()による変換)でも問題ないという認識でよろしいのでしょうか。
※ちなみに元になるバージョン情報の規格はASCHIコードでした。
宜しくお願い致します。




引用返信 編集キー/
■5915 / inTopicNo.10)  Re[9]: BTSTR の受け渡し方法について
□投稿者/ Blue (327回)-(2007/07/26(Thu) 10:48:30)
よく見たら
>sprintf(getVer, '\0', (const char *)bVersion); //A const charでキャストし、char型の文字配列に格納
ってあっていますか?
単なるコピーならstrcpyでよいのでは?

>※ちなみに元になるバージョン情報の規格はASCHIコードでした。
がよくわからないですね。
ASCIIコードだとしても、C#で扱うときはUnicodeで扱われると思うのですが。

>元データが固定長(128byte以下、常に固定長)で保障されているような場合
なら大丈夫だと思います。

けど、C#側のコードを見てみないと確証はないです。
(できるならC側で領域を用意してC#側でそれに入れるというようなつくりにしたほうが間違いないと思う。)
引用返信 編集キー/
■5954 / inTopicNo.11)  Re[10]: BTSTR の受け渡し方法について
□投稿者/ siroisi (7回)-(2007/07/27(Fri) 00:30:25)
No5915 (Blue さん) に返信

ご返答有難うございます。
> よく見たら
> >sprintf(getVer, '\0', (const char *)bVersion); //A const charでキャストし、char型の文字配列に格納
> ってあっていますか?
> 単なるコピーならstrcpyでよいのでは?

間違っておりました。以下のように格納しました。

sprintf(getVer, '%s', (const char *)bVersion);

> 単なるコピーならstrcpyでよいのでは?

b_str_t 型の変数に対して、strcpy()を使用できたのですか?
てっきり、str関数は使えないものと思っておりました。
ちなみに、b_str_t 型はNULL保障されているのでしょうか?

> >元データが固定長(128byte以下、常に固定長)で保障されているような場合
> なら大丈夫だと思います。
>
> けど、C#側のコードを見てみないと確証はないです。
> (できるならC側で領域を用意してC#側でそれに入れるというようなつくりにしたほうが間違いないと思う。)

勝手な理由ですが、今の作りを変えたくないというのが、正直な気持ちで・・・
現時点では、元データのサイズを計り、それを超えていたら、フォーマットエラーにするというのが
自分にとって、ベストと思っております。
あとは、b_str_t 型のサイズを計る方法を調べてみます。
わからない場合には、またお尋ねしてしまうかもしれませんが
よろしくお願い致します。
今回のアドバイスには本当に助かりました。
ありがとうございました。




引用返信 編集キー/
■5955 / inTopicNo.12)  Re[11]: BTSTR の受け渡し方法について
□投稿者/ siroisi (8回)-(2007/07/27(Fri) 00:31:24)
No5954 (siroisi さん) に返信
> ■No5915 (Blue さん) に返信
>
> ご返答有難うございます。
>>よく見たら
>>>sprintf(getVer, '\0', (const char *)bVersion); //A const charでキャストし、char型の文字配列に格納
>>ってあっていますか?
>>単なるコピーならstrcpyでよいのでは?
>
> 間違っておりました。以下のように格納しました。
>
> sprintf(getVer, '%s', (const char *)bVersion);
>
>>単なるコピーならstrcpyでよいのでは?
>
> b_str_t 型の変数に対して、strcpy()を使用できたのですか?
> てっきり、str関数は使えないものと思っておりました。
> ちなみに、b_str_t 型はNULL保障されているのでしょうか?
>
>>>元データが固定長(128byte以下、常に固定長)で保障されているような場合
>>なら大丈夫だと思います。
>>
>>けど、C#側のコードを見てみないと確証はないです。
>>(できるならC側で領域を用意してC#側でそれに入れるというようなつくりにしたほうが間違いないと思う。)
>
> 勝手な理由ですが、今の作りを変えたくないというのが、正直な気持ちで・・・
> 現時点では、元データのサイズを計り、それを超えていたら、フォーマットエラーにするというのが
> 自分にとって、ベストと思っております。
> あとは、b_str_t 型のサイズを計る方法を調べてみます。
> わからない場合には、またお尋ねしてしまうかもしれませんが
> よろしくお願い致します。
> 今回のアドバイスには本当に助かりました。
> ありがとうございました。
>
>
>
>
解決済み
引用返信 編集キー/
■5956 / inTopicNo.13)  Re[12]: BTSTR の受け渡し方法について
□投稿者/ Blue (328回)-(2007/07/27(Fri) 00:52:33)
>sprintf(getVer, '%s', (const char *)bVersion);
まだ違っていますけど。

>b_str_t 型の変数に対して、strcpy()を使用できたのですか?
>てっきり、str関数は使えないものと思っておりました。
const char*の文字列が取得できれば普通につかえます。

>ちなみに、b_str_t 型はNULL保障されているのでしょうか?
はい。
BSTRでGoogle検索してみてください。いろいろ解説しているサイトがありますよ。

ちなみにb_str_t型ではなくbstr_t(もしくは_bstr_t)"クラス"です。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -