• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C++のActiveX DLLでポインタを受け取る)

C++のActiveX DLLでポインタを受け取る

このQ&Aのポイント
  • C++でVB用にポインタをラップするようなクラスを作成し、正しいポインタを受け取る方法を教えてください。
  • ActiveX DLLを使用してVBからByRefで変数を受け取り、そのポインタを保持し、参照先の変数の値を取得したり代入したりする方法を教えてください。
  • 初めてIDLファイルを使用するため、ByRefで正しいポインタを受け取る方法を教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

>>STDMETHODIMP CLongRef::get_Ptr(long *pVal) >としたのは、long**にするとVBで扱えなくなってしまったからです。 なるほど、試してみましたが確かに VB ではエラーになってしまいました。 プロパティとして考えると違和感がありますが、これはこれで仕方がないかなと思います。 >[id(3), helpstring("メソッド setPtr")] HRESULT setPtr([in] long* newVal); >を作ってみたのですが、結果が同じでした。 私も試してみましたが、意図したものになりましたよ。 .idl ================================================================================== [propget, id(1), helpstring("プロパティ Ptr")] HRESULT Ptr([out, retval] long * pVal); [id(3), helpstring("メソッド SetPtr")] HRESULT SetPtr(long * newVal); .cpp ================================================================================== STDMETHODIMP CLongRef::get_Ptr(long * pVal) { *pVal = (long)m_ptr; return S_OK; } STDMETHODIMP CLongRef::SetPtr(long * newVal) { m_ptr = newVal; return S_OK; } VB ================================================================================== Dim X As Long Dim Y As New LongRef X = 100 Debug.Print "VarPtr(X) = " & VarPtr(X) 'Y.Ptr = X Y.SetPtr X Debug.Print "Y.Ptr = " & Y.Ptr 実行結果 ================================================================================== VarPtr(X) = 1306696 Y.Ptr = 1306696 STDMETHODIMP CLongRef::SetPtr(long * newVal) の中身はどのようになってますか? >idlとcppとhだけだと思っていたのですが、他にも対にしなければならないものがありますか? .idl、.cpp、.h だけで良いと思います。

haporu
質問者

お礼

遅くなってすみません。 >私も試してみましたが、意図したものになりましたよ もういちどクラスからウィザードで作り直したら、意図した結果になりました。 やはり、クラスウィザードが管理している触ってはいけない部分を、いつの間にか変えてしまっていたのかもしれません。 また、Long変数をputしてlong*の値をgetするのも変なので、Ptrプロパティは単にm_ptrをLongとしてラップするプロパティとして、SetPtrを別に設けることにします。 ありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (1)

回答No.1

VB では Integer や Long 等の値型の変数に対して Z = X のようにすると値渡しで代入されます。これは代入先がプロパティの場合でも同じです。 つまり、 Y.Ptr = X とすると、VB 側で X のコピーが作られ、X のコピーが Y.Ptr に渡されます。 STDMETHODIMP CLongRef::put_Ptr(long *newVal) の newVal は [ X のコピーのアドレス] になります。 VB の言語仕様として Integer や Long の参照型変数というものがない以上、プロパティで参照渡しはできないでしょう。 なので、プロパティでなく関数にしなければならないと思います。(いうまでもなく、引数は参照渡しにしなければなりません。) 実行結果が >VarPtr(X) = 1308376 >Y.Ptr = 1929464 のように、値が大きく異なっているのは、 STDMETHODIMP CLongRef::get_Ptr(long **pVal) とすべきところが STDMETHODIMP CLongRef::get_Ptr(long *pVal) となっているためではないかと思います。 ( ただしいコピーのアドレスであれば、もっと近い値になるのあ普通だと思います。) ちなみに、VB は 6.0 ですか?

haporu
質問者

補足

解凍ありがとうございます。 すいません、バージョンを書いていませんでした。 VBもVC++も6.0です。 >STDMETHODIMP CLongRef::get_Ptr(long *pVal) としたのは、long**にするとVBで扱えなくなってしまったからです。 >VB の言語仕様として Integer や Long の参照型変数というものがない以上、プロパティで参照渡しはできないでしょう VBで書いたら以下のようになることを、C++で書こうと思いました。 Property Get Ptr() As Long Ptr = m_ptr End Property Property Let Ptr(ByRef RHS As Long) m_ptr = VarPtr(RHS) End Property 上記のコードではLetで実際に渡るのはLongポインタで、Getで返すのはLong値だとおもいます。 このため、long *pValとしましたが、イレギュラーでしょうか・・・? ためしに、 [id(3), helpstring("メソッド setPtr")] HRESULT setPtr([in] long* newVal); を作ってみたのですが、結果が同じでした。 ためしに、別のクラスVariantRefを作って同じようなことをやってみたのですが、 [id(3), helpstring("メソッド setPtr")] HRESULT setPtr([in] VARIANT* newVal); は、ちゃんと正しいなポインタを受取れました。 あとから作ったVariantRefはプロパティとメソッドの作成をすべてウィザードに任せたのですが、LongRefでは試行錯誤しながらだったので、メンバを作ったり消したり、型を変えたりしてしまったのが行かなかったのでしょうか? ウィザードがメンバの作成時に追記したのは、質問のところで書いた、idlとcppとhだけだと思っていたのですが、他にも対にしなければならないものがありますか? VBでクラスを作ったり、C++で普通のクラスを作ったりはしているのですが、C++でATLクラスを作るのは初めてなうえ、文献もあまり見つからないため、ご教授いただきたいと思っております。

すると、全ての回答が全文表示されます。

関連するQ&A