こんばんは.
現在,VCでdllを作成し,VBでそれを動かしています.
ところが,dllを動かしたあとにプログラムが終了してしまいます.
エラーなど出ていないのにです.
dllではVBで受け取ったデータを元に計算を行い,それをfprintfで出力しています.
出力されたファイルを見る限り思い通りの計算はできているのですが・・・.
誰か原因が分かる方アドバイスください.
環境はVB,VCともに6.0,Win2000です
VC、VB共にどのように関数を宣言しているか書いてくれますか?
VC++(dll側は)
_declspec(dllexport) short _stdcall AveBrightMain(HDC hDC,char *filename)
VB
Private Declare Function AveBrightMain Lib "D:\vc\Testdll\Debug\Testdll.dll" (ByVal hDC As Long, ByVal filaname As String) As Integer
です.よろしくお願いします.
両方のデバッグできるように、
仮にVBでexeを作成し、VCでデバッグ用プログラムをVBで作成したexeを指定し、
デバッグしてみてはどうでしょうか?
> ところが,dllを動かしたあとにプログラムが終了してしまいます.
だと、VC側で落ちている可能性が高いかと。
素早い返答大変ありがとうございます.
確かにdll側みたいです.
デバッグすると↓のようになりました.
例外処理 (初回) は Project1.exe にあります: 0xC0000005: Access Violation。
しかし,ステップインさせていくと,全部のコードが終わった後にエラーが出ています.ので???な感じです.とりあえず,もう少し考えています.
> 全部のコードが終わった後にエラーが出ています
デストラクタかなんかかなぁ。。。
具体的にソースが載せれるならば、載せれていただけるとうれしいです。
大変お世話になります.
プログラムとしては[画像ファイルのパスが書いてあるデータ]を読み込んで,
画像の輝度値の平均値を順に出力するプログラムとなっています.
データは次のような感じです
520.bmp
110.bmp
210.bmp
ソースは次のような感じです
_declspec(dllexport) void _stdcall AveBrightMain(HDC hDC,char *filename){
char image_in[Y_SIZE][X_SIZE][3]; // 入力カラー画像配列
FILE *fp1,*fp2;
char s[256];
int len,avebright;
if ((fp1 = fopen(filename, "r")) == NULL) {
TextOut(hDC,10,10,"r file open error!!",17);
exit(1);
}
if ((fp2 = fopen("kekka.txt", "w")) == NULL) {
TextOut(hDC,10,10,"w file open error!!",17);
exit(1);
}
/*平均値ファイル出力*/
/* (4)ファイルの読み(書き)*/
while (fgets(s, 256, fp1) != NULL) {
len=strlen(s);
if(s[len-1]=='\n'){
s[len-1]='\0';
}
readBMP(s, image_in);
avebright=AveBrightness(image_in);
fprintf(fp2,"%d\n",avebright);
}
fclose(fp1);
fclose(fp2);
}
>> 全部のコードが終わった後にエラーが出ています
>デストラクタかなんかかなぁ。。。
全部のコードの後ということは、Blueさんの言うように、(例えば)global変数オブジェクト
のデストラクタで不正アドレス参照とかの可能性があるので、↑のコードだけでは何とも
言えないと思いますよ。
かと言って「ここを示せ」とはっきり言える状況でもないわけですが。
# でも、CRTにしろMFCにしろ、デバッグモードならデストラクタとかもステップ実行
# されませんかね…??
一応、問題をはっきり切り分けるために、VBからではなく、dllの利用側もVCにして再現
するかを確認するという手はあると思います。
これで、VBは完全に無関係と切り分けられるかと。
直接関係ないけど、
> if ((fp1 = fopen(filename, "r")) == NULL) {
> TextOut(hDC,10,10,"r file open error!!",17);
> exit(1);
> }
BeginPaint関数で、文字を描くよというふうに宣言しなくてもいいのでしょか。。。
私ですと、
> _declspec(dllexport) void _stdcall AveBrightMain(HDC hDC,char *filename){
ではなくて、
_declspec(dllexport) HRESULT _stdcall AveBrightMain( LPCSTR filename )
にして、戻り値としてどんなエラーがあったかを返すほうがいいかと思います。
メッセージが動的に変わるのならば、
_declspec(dllexport) HRESULT _stdcall AveBrightMain( LPCSTR filename, LPCSTR errormsg )
または
_declspec(dllexport) HRESULT _stdcall AveBrightMain( LPCSTR filename, VARIANT* errormsg )
みたいにします。
細かいですが、
> len=strlen(s);
> if(s[len-1]=='\n'){
> s[len-1]='\0';
> }
len == 0 の場合これだとよろしくなさそうなので、
char* nl = strchr( s, '\n' );
if ( nl ) n1 = '\0';
のようにしたほうがいいです。
> 一応、問題をはっきり切り分けるために、VBからではなく、dllの利用側もVCにして再現
> するかを確認するという手はあると思います。
には賛成です。
typo orz
> if ( nl ) n1 = '\0';
if ( nl ) nl = '\0';
また間違えてる。。。 ( ´△`)アァー
> if ( nl ) nl = '\0';
if ( nl ) *nl = '\0';
訂正
> _declspec(dllexport) HRESULT _stdcall AveBrightMain( LPCSTR filename, LPCSTR errormsg )
>または
>_declspec(dllexport) HRESULT _stdcall AveBrightMain( LPCSTR filename, VARIANT* errormsg )
_declspec(dllexport) HRESULT _stdcall AveBrightMain( LPCSTR filename, LPSTR errormsg )
または
_declspec(dllexport) HRESULT _stdcall AveBrightMain( LPCSTR filename, VARIANT* errormsg )
または
_declspec(dllexport) HRESULT _stdcall AveBrightMain( LPCSTR filename, BSTR* errormsg )
みなさん丁寧なレスありがとうございます.
ちょっと忙しいのでVC++でdll動かすのは明日になりそうです.
逃げてるわけではないのでご了承を.
返事遅くなりました.
まず,ソースのアドバイスありがとうございます.
で,肝心の結果なのですが・・・.
何度も試しているうちに勝手に解決してしまいました.
ただ,VC++で動かしたときとVBで動かしたときの動作が異なっていました.
ただ,char image_in[Y_SIZE][X_SIZE][3];がグローバルにしたときにうまくいったのでこの変の理解が足りてなかったのかも知れません・・.
ツイート | ![]() |