ファイルポインタを用いたDLLを作るには

解決


nao  2006-12-19 18:27:27  No: 64006  IP: 192.*.*.*

C++6.0でDLLを作成し,そのDLLをVC++6.0で使用しています.
DLLを作成するときにファイルポインタを使う関数は使用できません.
例えば,ヘッダに

#define EXTERN extern "C" __declspec(dllexport)
EXTERN int __stdcall wave_split_trig(char *,double,double,double);
EXTERN int __stdcall wave_max(FILE *,long,long &,long &);

として,DLLを作成し,使用するとすると
「error C2065: 'FILE' : 定義されていない識別子です。」
というエラーメッセージが出ます.ヘッダの一番下の行をなくし

#define EXTERN extern "C" __declspec(dllexport)
EXTERN int __stdcall wave_split_trig(char *,double,double,double);

とするとうまくいきます.
「FILE」を使うファンクションはDLLにすることはできないのでしょうか.

編集 削除
jackdaw  2006-12-19 19:01:56  No: 64007  IP: 192.*.*.*

FILEが定義されているヘッダを#includeしたらいいと思います。
間違っていたらごめんなさい。

編集 削除
nao  2006-12-19 19:29:32  No: 64008  IP: 192.*.*.*

> FILEが定義されているヘッダを#includeしたらいいと思います。

FILEが定義されているヘッダというのはstdio.hだと思うのですが,
#include <stdio.h>は最初に宣言しています.

編集 削除
シャノン  2006-12-19 21:19:27  No: 64009  IP: 192.*.*.*

#ちょっと本題を外れますが。

> C++6.0でDLLを作成し,そのDLLをVC++6.0で使用しています.

このように、DLL を作成する環境と、それを使用する環境は常に同じである、という保証はありますか?
もし、その保証がないのであれば、このような DLL は作成すべきではありません。

編集 削除
nao  2006-12-20 16:14:00  No: 64010  IP: 192.*.*.*

保証という意味がよくわかりません.
本当はVCで作ったDLLをVBで使うのが目的ですが,本当にそのDLLが動作するのかを,
VCで作ったDLLが動作するかで確かめています.
DLLを作成する環境と使用する環境はいっしょであると問題なのでしょうか.

編集 削除
Blue  2006-12-20 16:32:03  No: 64011  IP: 192.*.*.*

>DLLをVBで使うのが目的
OUTでしょ。

VBからしたらFILEなんて意味不明なポインタでしかなさそうですが。
VBでは別にFILE*の値を使わないのであれば void* とかにしておけばどうでしょうか。
で、使うときにキャストする。


という方法はクラスをDLLにするようなときによく使います。

編集 削除
シャノン  2006-12-20 17:21:05  No: 64012  IP: 192.*.*.*

> 保証という意味がよくわかりません.

以下の2点が保証できるか、ということです。
1:この DLL は、あなたの作る EXE でしか使わないこと。
2:DLL と EXE をビルドするのに、違うコンパイラ(※)を使わないこと。

例えば、この DLL だけをネット上で公開すると、他人がその DLL を利用する EXE を VC++ 2005 とか Borland C++ とかで書く可能性があります。
このように、DLL を作るコンパイラと、DLL を使う EXE を作るコンパイラが違うと、関数が正常に呼び出せない可能性があります。

※正しくはコンパイラではなくラインタイムライブラリですが。

> 本当はVCで作ったDLLをVBで使うのが目的ですが,

VB では fopen が呼べませんが、どうやって引数に渡す FILE* を得るのですか?

編集 削除
nao  2006-12-20 18:17:41  No: 64013  IP: 192.*.*.*

勉強不足ですみません。保証できます。
たしかにFILEを使うとVBでは無理な気がします。
最初はDLLの中の一つの関数だけを使うつもりだったんですけど、
一応すべての関数も使えるようにしようと思ったんで。
先のことを考えてませんでした。すみません。

でも、VCで作ったDLLをVCでなら使用できると思うのですが。
FILE*を使うと最初に言ったようなエラーが出てしまいます。
DLLの作成時にFILE*は使えないのでしょうか。
よろしくおねがいします。

編集 削除
シャノン  2006-12-20 19:25:04  No: 64014  IP: 192.*.*.*

そのエラーが出ている行を含むファイルの内容を載せてみてください。
関数の中身は要りませんので、ファイルの先頭から、以下のような感じで。

#include "..."

EXTERN int __stdcall wave_split_trig(char *,double,double,double)
{
    // 中身は載せなくていいです。
}

EXTERN int __stdcall wave_max(FILE *,long,long &,long &)
{
    // 要りません。
}

編集 削除
YuO  2006-12-20 20:25:49  No: 64015  IP: 192.*.*.*

> このように、DLL を作成する環境と、それを使用する環境は常に同じである、という保証はありますか?
ついでに,使うCRTが同一のDLL版である保証も要りますね。
片方がデバッグ版,片方がリリース版ではだめです。

編集 削除
nao  2006-12-21 12:24:46  No: 64016  IP: 192.*.*.*

遅くなってすみません.作ったDLLのソースは

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#include "wave_split_trig6.h"          //ヘッダのインクルード
#define INTRTN EXTERN int __stdcall     //型の定義

INTRTN wave_split_trig(char *f_in,double trig_percent,double split_length_t,double pretrig_length_t){…}

INTRTN check_header(FILE *f){…}

INTRTN split_level(FILE *f,char *f_in,unsigned char *header,long wave_length_n,long trig_level,long split_length_n,long pretrig_length_n){…}

INTRTN get_parameter_header(unsigned char *header,long &wave_length_n,long &fs,short &nch,long &nbit){…}

INTRTN wave_split(FILE *f,unsigned char *header,long split_position,long split_length_n,char *f_out){…}

INTRTN wave_max(FILE *f,long wave_length_n,long &max_level,long &max_position){…}

INTRTN change_byte_header(unsigned char *header,long split_length_n){…}

INTRTN str_insert_number(char *f_in,long number,char *f_out){…}

ヘッダの部分が
#define EXTERN extern "C" __declspec(dllexport)

EXTERN int __stdcall wave_split_trig(char *,double,double,double);
EXTERN int __stdcall check_header(FILE *);
EXTERN int __stdcall get_parameter_header(unsigned char *,long &,long &,short &,long &);
EXTERN int __stdcall change_byte_header(unsigned char *,long);
EXTERN int __stdcall str_insert_number(char *,long,char *);
EXTERN int __stdcall wave_max(FILE *,long,long &,long &);
EXTERN int __stdcall wave_split(FILE *,unsigned char *,long,long,char *);
EXTERN int __stdcall split_level(FILE *,char *,unsigned char *,long,long,long,long);

としています.このDLLをコールすると,FILEのところでエラーが出ます.FILEを含むファンクションをなくすとうまくいきます.
どうしてでしょうか.よろしくおねがいします.

編集 削除
シャノン  2006-12-21 12:39:58  No: 64017  IP: 192.*.*.*

> このDLLをコールすると,FILEのところでエラーが出ます

ちょっと待って。「DLLをコール」って何?
エラーが出るのは実行時なの?  コンパイル時だよね?

編集 削除
シャノン  2006-12-21 12:51:36  No: 64018  IP: 192.*.*.*

> #include "wave_split_trig6.h"          //ヘッダのインクルード
> #define INTRTN EXTERN int __stdcall    //型の定義

このコメントは実際のソースにもついていますか?
ついているなら、削除してみるとどうなりますか?

編集 削除
tetrapod  2006-12-21 12:57:17  No: 64019  IP: 192.*.*.*

なんだか話が変だけど、どうも見てるにみんな混乱してるような気がする。
・DLL を作る側の話 (hoge.dll)
・DLL を使う側の話 (piyo.exe)
どっち?

FILE* をソースコード上で使うダミー DLL を作ったけど問題ないよ。

使う側の話なら piyo.exe に対応する piyo.c/piyo.cpp で
#include "hoge.h" する前に #include <stdio.h> が必要。
または hoge.h 中で #include <stdio.h> するか。

まあいずれにせよ VB にとっては FILE って意味がないので再考察が必要。

編集 削除
nao  2006-12-21 14:56:28  No: 64020  IP: 192.*.*.*

> エラーが出るのは実行時なの?  コンパイル時だよね?

すみません.コンパイル時のエラーです.

> ・DLL を作る側の話 (hoge.dll)
> ・DLL を使う側の話 (piyo.exe)
> どっち?

DLLを使うときの話です.

> #include "hoge.h" する前に #include <stdio.h> が必要。

#include <stdio.h>の前にヘッダをインクルードしていました.
#include <stdio.h>を先にするとエラーがなくなりました.

これからはもっと聞きたいことを整理して質問するようにします.
すみません.
教えてくださったみなさん,本当にありがとうございました.

編集 削除