01-14-2015 01:30 AM
現在、下記環境でviにDLLを組み込もうと考えていますが、ある関数を実行すると「エラーコード1097」が発生します。
OS :Windows7 Professional(32ビットOS)
LabVIEW :LabVIEW2011(SP1) バージョン11.0.1f2(32-bit)
【関数の定義及びライブラリ関数の設定】
関数定義 :int WINAPI xxxxx(unsigned char *BUF, unsigned long LEN) ※xxxxxは関数名
スレッド :UIスレッドで実行
呼び出し規約 :stdcall(WINAPI)
パラメータ :返り値タイプ=数値、符号付き32ビット整数
BUF=配列、符号なし8ビット整数、次元=1、配列データポインタ
LEN=数値、符号なし64ビット整数、値
また、実際にvi上で設定しているサイズとしては"827392"(BUFの配列要素数及びLENの値)になります。
正直な所、どこに原因があるのか全くわかっていない状況です。
但し、C言語ベースに上記DLLを組み込んだ際には動作している為、少なくともDLLは動作していると考えていますが、
C言語も、それほど理解している訳では無いので、実際の所はどうかわかりません。
詳細が不明、且つ、拙い文章で申し訳ありませんが、対応策についてご助言頂ければ幸いです。
以上です。
01-14-2015 05:48 AM
呼び出しが整合していないように思われますが、多くの場合は、呼び出し規約が異なるか
引数の型が合っていない場合になりますが、前者は今回 C の方でも WINAPI (= __stdcall)
と明示しているので大丈夫そうなので、以下の点は如何でしょうか。
●引数の型
引数 LEN は、Cソースでは unsigned long になっているようですが、LabVIEW側は64bit整数で良いでしょうか?
64bit整数だと、Cでは (unsigned) long long のように記述されるかと思います。
LabVIEW側の LEN の型を、符号なし32bit整数にすると、どうでしょうか?
LENの分を、4バイトしかスタックを積んでいないのに、帰る時に8バイト捨てて戻ろうとするので
戻りアドレスが変なところになってしまうとか・・・
ちなみに御存知かも知れませんが、short, int, long などの実際のサイズは処理系に依存し、
必ずしも short < int < long とは限らず、short ≦ int ≦ long であれば良いようで、
最近は多くの場合は short (16) < int (32) = long (32) のように思います。
それでも "int" と書かれると、16bitか32bitかどっちのつもりだろう・・・と悩んだりします。
手元の Visual Studio の C++ 2010 で sizeof( ) を使って型のサイズを調べると
short (16) < int (32) = long (32) < long long (64) でした。
01-15-2015 04:42 AM
自己レスです。
>>LENの分を、4バイトしかスタックを積んでいないのに、帰る時に8バイト捨てて戻ろうとするので
>>戻りアドレスが変なところになってしまうとか・・・
これのせいかどうかは別にして、表現が、逆でした。
「LENの分を、8バイト スタックに積んだのに、帰る時に4バイトしか捨てないで戻ろうとするので」
の方が正しいかも知れません。
(スタックの積む順序によっては、戻りアドレス云々の前に、配列の方の指すアドレスが
違うところを指していてそこにアクセスしようとしてエラーになっている可能性も)
01-18-2015 08:52 PM
Shiraishi様
ご回答ありがとうございました。
また、当方の確認が遅くなり、申し訳ありませんでした。
引数LENの型について符号なし32bitに変更してみましたが、動きませんでした。
また、戻り値に関しても、16bitにしてみたりしましたが、同様でした。
ひとまず、今後は該当の関数だけでは無く、この関数よりも前に呼び出している関数に対して型などを確認していこうと
考えています。
以上です。
01-19-2015 03:05 AM
本件、解決しました。
原因としてはBUFに配列を準備していたのですが、2周期目以降のBUFへの
INPUTが前周期のOUTPUTになっていたことでした。
(Whileループのシフトレジスタを用いて前周期のOUTをINに入れる)
そのため、BUFの値が空になってしまった際にBUF配列不足となり、
エラーとなっていたみたいです。
Shiraishi様
質問にご検討いただき、有難う御座いました。
以上です。