3つ前の質問とも関連した質問です.
VBやVC++単独のプログラムだとそれぞれの開発環境でデバッグが
可能ですが,VBやVC++のプログラムにまたがって,変数の値の変化
を追跡したり,メモリの確保や開放をモニターするようなデバッグ
の方法はないものでしょうか.
VBとVCにまたがってではないですが、私の場合、基本的に、
VB側でEXEを作成し、VC側からデバッグを実行します。
特に、メモリの確保や解放などは、VB側では細かく制御できないと思いますので、
VC側でそのVB側とのIFの部分で、まずIFでの引数の値をチェックし、
VC内で異常がないかチェックしていきます。
先の質問でも、どうもVC側でエラーが発生しているようなきもするので、
VC側を特に入念にデバッグされることをお勧めします。
KING・王さんのおっしゃる通り、私もVC側からデバッグを実行します。
VB側は、プロジェクトのプロパティで「最適化なし」「シンボリック
デバッグ情報を作成」を選択してEXEを作成し、VCのデバッグ実行で起動します。
今回は不要だと思いますが、VB側でOutputDebugString(API)をDeclare Functionして
呼び出すと、VBのプログラムからVCのアウトプットウィンドウにデバッグ出力
できます。
ちなみに、VBは構造体のアライメントが「4バイト」固定なので、構造体を
受け渡すVBプログラムと組み合わせるVCプログラム(DLL)は、プロジェクトの
設定で、「C/C++ → コード生成→ 構造体メンバのアライメント」を「4バイト」
に設定する癖をつけておいた方が良いでしょう。
KING・王さん,あいうさん,早速のお返事ありがとうござい
ます.また,VBで作成したプログラムをVC++上でデバッグを行うた
めのその方法についても,適切に誘導してくださりありがとうござ
います.
VB,VC++にまたがるプログラムでは,VB側でEXEを作成し、VC側
からデバッグを実行するということが分かり,このスレッドの目的
は達成されました.
しかし,それを行うとVBでFFTW.exeをつくり,VC++上でデバッグ
を行ってみたところ,下記のようになりました.アセンブラは初め
てで,この後どうすればよいのか正直分かりません.もしよろしけ
れば続けてアドバイスをお願いいたします.
「ハンドルされていない例外はFFTW.exe(FFTW3.DLL)にあります:
0xC0000005:Access Violation。」という文章がポップアップし,
混合モードと呼ばれるウィンドウは,
「(黄色)→014695B1 fld qword ptr [edx+esi]」
という状態で停止しました.クイックウォッチによりますと,上記
シンボル名に対して,「CXX0004:Error:構文エラーです」という値
が表示されました.
#ちがっていたらごめんなさい。
だいたい、VBとVCを連携させたプログラムと言う場合、
VBでEXEを作成し、VCでDLLを作成して、VB側からは、
VC内の関数をコールするという形になると思います。
ここで、VC側の関数の、VBから呼ばれる全ての関数の先頭に、
ブレイクポイントを設定して実行させます。
そして、VC側の関数がコールされ、ブレイクポイントで止まったら、
そこから、その関数がRETURNするまで、ステップ実行等を繰り返し、
VB側に制御が戻るまで実行していきます。
途中で、落ちるようならそこが原因ですし、そこで落ちず、
次のVC側の関数コールもなされないままで、落ちるならVC側には問題がなく、
VB側に問題がある可能性が高いです。
(VC側に問題がある可能性も否定できませんが。。。)
ということで、この場合は、VB側からデバッグしてみるとになります。
ここで、ポイントとして、VC側の関数がVB側からコールされたときに、
関数の引数と、その関数からVB側に制御を返す場合の戻り値の値及び、
参照渡しされた関数の引数などをよくチェックして見て下さい。
地道な作業になりますが、まずVB側かVC側か、どちらに問題があるのかを
切り分ける、その後、細かく原因の特定していくしかないと思います。
#なお、VC側がスレッドを実行しているなどとなると、
#この方法だけでは、簡単には見つからないかもしれませんが。
#駄レスですが
> ここで、VC側の関数の、VBから呼ばれる全ての関数の先頭に、
> ブレイクポイントを設定して実行させます。
VB のコードにもブレイク張れたと思います。
停止したところで、VCのメニューから
「表示 → デバッグウィンドウ → コールスタック」
を選択すると、関数の呼び出し履歴が表示されます。
コールスタック上でダブルクリックすると、選択した
ソースを開きますので、最後に実行している自分のソース
を開き、変数内容などを確認してみてください。
また、上で開いた関数の先頭にブレイクポイントを設定して
改めて最初から実行し、ブレイクポイントで停止後、
ステップ実行してみるのも良いかもしれません。
KING・王さん,シャノンさん,あいうさん,貴重なアドバイ
スをどうも有難うございます.長文で申し訳ありませんが,以下の
ように報告させていただきます.
混合モードのウインドウにアセンブラが出たときはどうしようか
と思いましたが,VC++のソース中にブレークポイントを入れること
で,混合モードのアセンブラ中にVC++のコードが表示されるほか,
ソースコードでもその進行状況が示されることが分かりました.
デバッグを行った結果,「ハンドルされていない例外は
FFTW.exe(FFTW3.DLL)にあります:0xC0000005:Access Violation。」
という表示は,FTTW.cppとして作成したファイルの以下の部分で生
じていることが分かりました.fftw_executeは目的にそったフーリ
エ変換を行わせる関数部分で,
http://www.fftw.org/install/windows.htmlからダウンロードした
FFTW3.DLLに含まれているものです.
35: fftw_execute(p); /* repeat as needed */
●100010BF mov ecx,dword ptr [ebp-0Ch]
100010C2 push ecx
100010C3 call fftw_execute (1000113e)
100010C8 add esp,4
上記関数はVBから呼び出された,
FFTW_API void __stdcall dft_1d(int n, fftw_complex *FFTWin, fftw_complex *FFTWout, int sign)
の中の関数ですが,実際にVBから正しく値を受け取っているか,変
数の値を追跡してみました.呼び出し元はVB中で,
Call dft_1d(i - 1, FFTin(0), FFTout(0), FFTW_FORWARD)
と書かれています.
まず,変だったのは,VB上でi-1の値が3229であるのに対し,値
を受け取った,VC++側のnは1242172という値になっていました.さ
らに,VB上ではFFTW_FORWARD=-1にも関わらず,VC++のsignは17367072
となっていました.
つまり,まず,第一の問題としてVBからVC++へ値の受け渡しがう
まくいっていないことが挙げられると思います.
また,プログラムが停止した場所でコールスタックを出すと
FFTW3! 014595b1()
baadf00d()
のように表示され,ダブルクリックすことにより,
014595B1 fld qword ptr [edx+esi]
で停止していることが分かりました.
デバッグ中にコールスタックを開こうとすると,「問題が発生し
たため,msdev.exe を終了します。ご不便をおかけして申し訳あり
ません。」というメッセージが出て,VC++のワークスペース全てが
落ちてしまいました.そしてその後,「msdev.exe - アプリケー
ションエラー - "0x7c950de3"の命令が"0xfffffff8"のメモリを参
照しました。メモリが"read"になることはできませんでした。」と
なりました.これは一体どういうことなのでしょうか.
出力してくれたエラー「Access Violation」の意味を理解することが
原因特定への近道です。
int型引数の内容を確認したところまではよかったのですが、全ての
引数の内容を確認してみてください。
「FFTWin」に変数のアドレスでは無く、「i-1」の値が入っていたり
しませんか?
> 上記関数はVBから呼び出された,
>FFTW_API void __stdcall dft_1d(int n, fftw_complex *FFTWin, fftw_complex *FFTWout, int sign)
のところに、VBの「Declare」宣言を併記すると、原因の特定が容易
だったかもしれません。
DLL中の「dft_1d」関数はvoid型ですよね?
VBの関数で戻り値がない場合は「Function」宣言ではなく、「Sub」
宣言をしますよね?
--------------------------------------------------------------------
始めに
> 3つ前の質問とも関連した質問です.
#この書き方もよりも、リンクを張っておいたほうが解りやすいかも。
とあったので、元発言
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110020.txt
を確認させていただきました。
いやいや,過去ログって便利ですね.多くの人が同様な問題に取り組んでき
たんだな,としみじみ感じます.DLLのデバッグ方法は,今回の私の問題にも
通じており,参考にさせていただきました.
http://madia.world.coocan.jp/vc/vc_bbs/200410_04100011.html
さて,dft_1d(i - 1, FFTin(0), FFTout(0), FFTW_FORWARD)の変数ですが,
VB VC++
i-1 = 3229 n = 1242172
FFTin(0) = Sample.txtから読んだ値 *FFTWin = 0x00000ce3
FFTout(0) = 全て0 *FFTWout = 0x00f90020
FFTW_FORWARD = -1 sign = 17432608
上記のようになりました.ただし,VBの値はVC++に組み込んだexeファイル
の値ではなく,VBのプロジェクト上の値です.
また,*FFTWin,*FFTWoutのメモリはそれぞれ,以下のようです.
FFTout(0)の値はVBでは全て0ですが,VC++では値があるのが気にかかります.
*FFTWin
00000CE3 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??????????????
00000CF1 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??????????????
00000CFF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??????????????
・
・
・
*FFTWout
00F90020 00 00 00 00 00 30 D1 3F 00 00 00 00 00 00 .....0ム?......
00F9002E 00 00 00 00 00 00 00 20 D2 3F 00 00 00 00 ....... メ?....
00F9003C 00 00 00 00 00 00 00 00 00 20 D2 3F 00 00 ......... メ?..
・
・
・
>DLL中の「dft_1d」関数はvoid型ですよね?
>VBの関数で戻り値がない場合は「Function」宣言ではなく、
>「Sub」宣言をしますよね?
仰るとおりでした.早速訂正を致しました.
また,Access Violationの件ですが,ここが参考になりました.
http://madia.world.coocan.jp/vc/vc_bbs/200410_04100024.html
警告レベルを4にしてビルドすると,DLLウィザードが自動的に作ってくれた
部分で,警告が2つ出ましたが,私の場合は問題がないようにも思います.
-----ウィザードが作成した部分--------------------------------
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
-----警告文-------------------------------------------
\\FFTW\FFTW.cpp(10) : warning C4100: 'lpReserved' :
引数は関数の本体部で 1 度も参照されません。
\\FFTW\FFTW.cpp(7) : warning C4100: 'hModule' :
引数は関数の本体部で 1 度も参照されません。
-------------------------------------------------------
VB側の値は「i-1 = 3299(0x00000ce3)」ですよね?
>FFTout(0)の値はVBでは全て0ですが,VC++では値があるのが気にかかります.
もう少し突っ込んで調べると、VBでFFTWinに格納した値が
VC側でFFTWoutに見えているのが解ると思います。
つまり、スタック上の引数読み出し位置が4バイトずれて
いたということです。
ワーニングが気になるようであれば、未使用の引数を型宣言のみに
変更すると、回避することが可能ですが、ご自身の判断通り
そのままでも問題ありません。
BOOL APIENTRY DllMain( HANDLE /*hModule*/,
DWORD ul_reason_for_call,
LPVOID /*lpReserved*/
)
で、本題は解決したのでしょうか?
>VB側の値は「i-1 = 3299(0x00000ce3)」ですよね?
仰る通りです.
先にi-1=3229と書いてしまいましたが,書き間違いでした.
>つまり、スタック上の引数読み出し位置が4バイトずれて
>いたということです。
なるほど!その通りかも知れない!!
...と思ったのですが,まだ以下のことが分からず,自力でデバッグでき
ません.くだらない質問かと思われるかもしれませんが,お願い致します.
1.FFTWinの値はVBでSample.txtの値(左下)を読んでいるのですが,
これがつまり,VC++で見たところのFFTWoutに格納されている値(右下)
FFTWin(VB) FFTWout(VC++)
0.2685546875 00000000 3FD13000
0.283203125 00000000 3FD22000
0.283203125 00000000 3FD22000
0.2734375 00000000 3FD18000
0.2783203125 00000000 3FD1D000 (Long Hex Format)
・ ・
・ ・
・ ・
に等しいと言うことですが,その変換はどうやるのですか.VC++のデバッ
グツールの中に,10進数を浮動小数点型の16進数に直すツールがあれば教
えて下さい.(windows付属の電卓で検算しようと思ったのですが,失敗し
ました.
2.読み出し位置が4バイトずれている原因
読み出し位置がずれたことは分かったのですが,なぜずれたのでしょう?
各関数の宣言文には,これ以上悪い所があるように思えないのですが.
結局これが理解できない私はまだ解決できないでいます...
>に等しいと言うことですが,その変換はどうやるのですか.VC++のデバッ
>グツールの中に,10進数を浮動小数点型の16進数に直すツールがあれば教
>えて下さい.(windows付属の電卓で検算しようと思ったのですが,失敗し
>ました.
VC側で適当なdoubleの変数を作成して値を代入し、その変数のアドレスを
「表示 → デバッグウィンドウ → メモリ」で指定すると、doubleの
バイナリ値を確認することが可能です。
>読み出し位置がずれたことは分かったのですが,なぜずれたのでしょう?
>各関数の宣言文には,これ以上悪い所があるように思えないのですが.
私も詳しくないので推測ですが、VB側で「Function(戻り値あり)」宣言
をしたため、戻り値領域(型が未指定のため、デフォルトで4バイト)
がスタック上に確保され、VC側では「void(戻り値なし)」宣言をしたため、
戻り値領域が無いものとして、引数を取り出した結果、4バイトずれたのだと
思います。
#間違えていたらごめんなさい。
あとは、元発言
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110020.txt
のレスで紹介されているリンクを理解すれば、解決すると思います。
#相互にリンクを張って片方を解決マークで閉め、一方で進行したほうが
良いでしょう。
まず,元発言の最後に書き込みをしてくださったYuoさんのコメントから説
明させてください.多少長くなりますが,お付き合いの程よろしくお願い致し
ます.
>Knowledge Base 410837
>[VB5] Visual Basic 5.0 から呼び出し可能な DLL の作成例
適切なプログラミングの例を示してくださり,有難うございます.
まだ,その例の全てを確認して,自分のプログラムへの適応および正常動作するかどうかの確認は行っておりませんが,取り急ぎ,私の見解を述べさせてください.
>FFTWoutに代入する行為も意味がわからなければ,
>直後にout(=FFTWout)のメモリを解放する行為の意味もわかりません。
DLLで作成したメモリはDLL内で開放しなけばいけない,ということを聞いたことがあります.そのため,out(DLLが確保したメモリ)をFFTWout(VBによりメモリが確保(されていると,私なりに考えました.))に移し,outを開放したのです.
多くのFFTプログラムの場合,元のデータが入っている配列にフーリエ変換後のデータを上書きして,関数の引用元に返すようですが,私が参考にしたプログラムでは,予め,元のデータと演算後のデータの配列が別個に用意されていたので,それに従いました.また,あのプログラムは,下記サイトから引用させていただきました.
http://www.fftw.org/fftw3_doc/Complex-One_002dDimensional-DFTs.html#Complex-One_002dDimensional-DFTs
私が最終的にやりたいことは,得られたデータに対して自動的にフーリエ変換を行うプログラムを作成することです.
フーリエ変換およびその他の理論数値計算に関わる計算そのものは,先哲の努力の甲斐が有り,その殆どがFortranやC/C++で書かれ,ライブラリ化されているのですが,残念ながら,その殆どはVBからは読み出せるようにはなっておりません.(多分...)
そこで,私は既存のライブラリをVBから使えるように,VC++でDLLを作ることを考えました.もちろん,VBなんて使わないで,全部をVC++で作れればそれに越したことはないのですが,以下の3つの理由によりVB⇔DLL(VC++で作成)⇔ライブラリの構図を考えました.
1.実験装置を駆動するアプリケーションの殆どはVBによって作成されている
(現存するリソースの有効活用)
2.VBは多少知っているが,VC++でアプリケーションを作ったことがない
(私自身のプログラミング技術の問題)
3.殆どのライブラリはC/C++で書かれている
(前述したように,VBからの直接的な利用はできないことが多い(多分))
そういう経緯があって,プログラミングを行っていましたが,どうしても自力では解決できない問題に直面し,このサイトで皆様からの助言を仰ごうという考えに至りました.
>とりあえず,KBを漁ってみるくらいはした方がよいです。
仰るとおりだと私もおもいました.
VBやVC++付属のMSDN,そしてインターネット上に書き込まれた様々な情報はよく調べるのですが,KBは概して簡単なことが難しく表現されている気概があり,また関連しそうなところを読んでも,結局それを自分の問題にフィードバックさせることができないことが多いので(つまり,KBを読んだあと,「で,結局私はどうすればいいの?」と感じることがあるので),避ける傾向にありました.少しでも,腰を据えて取り組むように致します.
あと,KBの問題としては自分が必要とする情報をピンポイントで抽出できないという点がありそうですね.googleなんかによる検索もそうでしょうが,例えば,http://support.microsoft.com/search/?adv=1で「VB DLL」と入れてもKnowledge Base 410837は出てきませんが,「Visual Basic DLL」と入れれば出てくる(それでも30番目)ようです.
Yuoさんご指摘有難うございました.
Knowledge Base 410837を確認の後また書き込みをさせていただきます.
> VC側で適当なdoubleの変数を作成して値を代入し、その変数のアドレスを
>「表示 → デバッグウィンドウ → メモリ」で指定すると、doubleの
>バイナリ値を確認することが可能です。
賢いですね.思わず,おおっと思ってしまいました.
>#相互にリンクを張って片方を解決マークで閉め、一方で進行したほうが
良いでしょう。
片方を解決マークで閉めておきました.
>私も詳しくないので推測ですが、VB側で「Function(戻り値あり)」宣言
>をしたため、戻り値領域(型が未指定のため、デフォルトで4バイト)
>がスタック上に確保され、VC側では「void(戻り値なし)」宣言をしたため、
>戻り値領域が無いものとして、引数を取り出した結果、4バイトずれたのだと
>思います。
>#間違えていたらごめんなさい。
FnctionをSubに置き換え,再度DLLを作成し,テストを行ったのですが,同じ結果でした.VBで作ったexeのパス等をもう一度確認してみます.
> DLLで作成したメモリはDLL内で開放しなけばいけない,ということを聞いたことがあります.そのため,out(DLLが確保したメモリ)をFFTWout(VBによりメモリが確保(されていると,私なりに考えました.))に移し,outを開放したのです.
>>> FFTWout = out;
は,fftw_complex型へのポインタ型を持つオブジェクトoutが保持している値(=ポインタ)を,
FFTWoutというオブジェクトにコピーしているだけです。
ポインタが指し示す先をコピーしているわけではありません。
とりあえず,Cの基礎を勉強する必要があると思いますよ。
...はい,とりあえず,Cから勉強します.
ところで,VBからVC++にデータを移行したときに4バイト分ずれていた原因
というのは,どうもあいうさんが指摘されていたように,FunctionとSubの記述の違いで,間違いないみたいです.
もう一度やり直したら,うまく値がVC++へ送られました.
そこで,FFTW.cppのdft_1dを下記のように書き直してみたところ,
FFTW_API void __stdcall dft_1d(int n, fftw_complex *in, fftw_complex *out, int sign)
{
fftw_plan p;
p = fftw_plan_dft_1d(n, in, out, sign, FFTW_ESTIMATE);
fftw_execute(p);
}
fftw_execute(p)の実行前と実行後で,値が変化しているのですが,
実行前 out(0x010a0020)
010A0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
010A0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
010A0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
010A0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
実行後 out(0x010a0020)
010A0020 00 00 00 00 E0 08 42 40 00 00 00 00 00 00 00 00
010A0030 34 73 FA BF 47 F3 4A 40 96 CA 35 4A BA 03 0D 40
010A0040 E8 77 53 11 92 D6 7C 40 A3 85 C6 2A 11 DE 7B 40
010A0050 5F A5 CD B4 7E DC 3B 40 96 10 A0 E3 A6 C0 56 C0
それがVBに反映されず,VBでみるとFFToutは全て0となっていました.
その理由と解決方法を教えてください.
おそらくこれが最後の質問になると思うのですが...
値渡しになっているとか…
RAPTさんどうも有難うございます.おそらくそれが原因だと思います.
VB側に,値が渡されるようになりました.
ところで,多少腑に落ちないのが,もともとVBでは以下のように宣言していたのですが,このときは,VBのFFTWoutは確かに0のままでした.
ただし,FunctionをSubに訂正済みです.
↓
Private Declare Function dft_1d Lib "FFTW.dll" _
(ByVal n As Long, FFTWin As fftw_complex, FFTWout As fftw_complex, ByVal sign As Long)
宣言文で,ByValとかByRefとか指定しなければByRefになりましたよね.
少なくとも,ByValだと,「ユーザー定義型はByValでは渡せません」というエ
ラーメッセージが出ます.
Option Explicitを宣言していたので,ByRefと明記しないといけないと思
い,ByRefを明記するとPARTさんの言うようにVBのFFTWoutに値が渡されるよう
になりました.
ところが,今度は逆にもう一度,ByRefを除くと,さっきまではうまく
FFTWoutに値が渡っていなかったのが,今度はきちんと渡るようになりまし
た.こんなことってあるのでしょうか.
あと,一連のデバッグ過程でもうひとつだけ変なことがありました.
VBのFormなどが入っているフォルダにSample.txtを入れて
Open "Sample.txt" For Input As #1
としていたのですが,「実行時エラー'53':ファイルが見つかりません」と出ました.
ところが,そのフォルダを,c:の直下に持ってきて実行させると,うまく
Sample.txtを認識し,そのあと,c:\xxxxx\xxxxx\xxxxx\と順番に階層を下げ
元の場所にまで戻ると,それらのどの階層でも,うまくSample.txtが読み込ま
れました.こんなことってあるのでしょうか.
多少謎は残りましたが,本題「VB,VC++にまたがるプログラムで,データの
値を追跡(いわゆるデバッグ)する方法を教えて下さい.」は解決しました.
結局のところ,VB,VC++上での単なる私の構文ミスが原因のようでした.
これまで,私の質問に対して親身になって回答してくださった,皆さん本当
にどうも有難うございました.また,何かあった際にはどうぞよろしくお願い
致します.
> Knowledge Base 410837を確認の後また書き込みをさせていただきます.
で、
> FFTW_API void __stdcall dft_1d(int n, fftw_complex *in, fftw_complex *out, int sign)
> {
> fftw_plan p;
> p = fftw_plan_dft_1d(n, in, out, sign, FFTW_ESTIMATE);
> fftw_execute(p);
> }
ですか。。。
「ユーザ定義型 (構造体) の配列の引き渡しの サンプル」を参考にすると
こんな感じになると思うのですが。
----------------------------------------------------------------------------
VC:
FFTW_API void __stdcall dft_1d(int n, LPSAFEARRAY *ppsaIn, LPSAFEARRAY *ppsaOut, int sign)
{
fftw_complex *in, *out;
//in・outのメモリ確保
//ppsaInをロック(SafeArrayLock)
//ppsaInに格納されている値を取り出し、inにコピー(SafeArrayGetElement)
//ppsaInのロック解除(SafeArrayUnlock)
//in・outに対して、fftwライブラリ呼び出し
//ppsaOutをロック(SafeArrayLock)
//outに格納されている値を取り出し、ppsaOutにコピー(SafeArrayPutElement)
//ppsaOutのロック解除(SafeArrayUnlock)
//in・outのメモリ開放
}
VB:
Private Declare Sub dft_1d Lib "FFTW.dll" _
(ByVal n As Long, FFTWin() As fftw_complex, FFTWout() As fftw_complex, ByVal sign As Long)
あっ、遅かったか。
ちなみに、ファイルのフルパスを指定しない場合、カレントディレクトリの
ファイルを開くので、フルパスを指定しておいた方が良いでしょう。
追記有難うございます.昨晩私もSAFEARRAYをみてみました.
そのことを書き込み忘れていました.
>ppsaInに格納されている値を取り出し、inにコピー(SafeArrayGetElement
私の場合は構造体の要素に直接アクセスする必要はないので,
SafeArrayCopy
SafeArrayCopyData
のどちらかを用いればよいかと思います.
それにしても,構造体で,safearrayを用いる理由というのは,なぜなんで
しょうか.
「ユーザ定義型 (構造体) の配列の引き渡しの サンプル」で,
「Variant 型 および SafeArray を用いて構造体配列の引き渡しを実現しま
す。 数値の配列の節で説明した先頭要素へのポインタを渡す方法は、その先
頭要素のみがメモリ上に配置されていることが保証され、後続の要素は (偶然
存在する場合もありますが) 配置されているとは限りません。」
のように説明されていますが,これは,構造体の各要素が,配列を宣言したと
きのように連続的にメモリが割り振られるのとは異なり,メモリ上ではバラバ
ラのアドレスに格納されることもあり得る,と解釈をすればよいのでしょう
か.
構造体や行列の要素に直接アクセスできる,例えばSafeArrayGetElementの
ような関数がそろっているというのは,非常に大きなメリットだとは思います
ね.
ツイート | ![]() |