jpegの処理について

[戻る]
せんべえ 2003/10/30(木) 16:53:00
私はWINXP VC++6.0(opengl)でjpeg画像の保存を試みているのですが、以下のようなエ
ラーが出てしまい、かれこれ3日間悩んでいるものです。
どうもjpeg-6bフォルダの中のjpeglib.hが原因のような気がしているのですがこれとい
って修正方法が分からないです。どなたか良いお考えをお持ちの方がいらっしゃいまし
たら宜しくお願いいたします。
imgjpeg.c
リンク中...
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_read_scanlines" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_destroy_decompress" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_finish_decompress" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_start_decompress" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_read_header" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_stdio_src" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_CreateDecompress" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_std_error" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_destroy_compress" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_finish_compress" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_write_scanlines" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_start_compress" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_set_quality" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_set_defaults" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_stdio_dest" は未解決です
imgjpeg.obj : error LNK2001: 外部シンボル "_jpeg_CreateCompress" は未解決です
Release/imgsavejpeg.exe : fatal error LNK1120: 外部参照 16 が未解決です。
link.exe の実行エラー

imgsavejpeg.exe - エラー 17、警告 0

SunPac 2003/10/30(木) 17:02:47
まずヘッダーファイルはインクルードしましたか?
ライブラリはリンカに認識されていますか?
まぁ、この辺が原因ではないかな。

プロジェクト − 設定 − リンク
ビルド − オプション − ディレクトリ

の設定を確認しましょう。

せんべえ 2003/10/30(木) 17:07:05
SunPacさん
こんなに早く返信してくださって有難うございます。
おしゃられる箇所を調べてみようと思います。

せんべえ 2003/10/30(木) 17:13:56
プロジェクト − 設定 − リンク
>ビルド − オプション − ディレクトリ
すいません。
上のほうはわかるのですが
下の流れが良く分からないのでご説明していただいてもよろしいでしょうか?
お手数おかけします。

sugar 2003/10/30(木) 17:16:18
ツール − オプション − ディレクトリ

だと思われます。

せんべえ 2003/10/30(木) 17:18:24
sugarさん有難うございました。
しばし、頑張ってみます。

もしかして・・・ 2003/10/30(木) 17:25:16
似たような質問がありますね。ただの偶然でしょうか?

http://forums.belution.com/ja/cpp/000/015/85.shtml

せんべえ 2003/10/30(木) 17:30:45
>似たような質問がありますね。ただの偶然でしょうか?
私はVCでコンパイルを行っているのですが・・・
すこし残念な思いです。
マルチではないです。

ところで、先ほどの二項目を試してみたのですが、まだ以前のままです。

sugar 2003/10/30(木) 17:41:37
jpeg-6bのソースから、libファイルをビルドしてますか?
そのlibファイルを、せんべえさんのプロジェクトからリンクしてますか?

せんべえ 2003/10/30(木) 18:30:20
返信有難うございました。
>jpeg-6bのソースから、libファイルをビルドしてますか?
jpeg-6bのソースからlibを作成しました。
>そのlibファイルを、せんべえさんのプロジェクトからリンクしてますか?
皆様がご教授してくださった方法でリンクしていると思われます。

sugar 2003/10/30(木) 18:39:28
「思われます」と言われると、「本当?」とつい疑ってしまふ…
「プロジェクト - 設定 - リンク」の「オブジェクト/ライブラリモジュール」は、
どんな設定をしていますか?

せんべえ 2003/10/30(木) 18:41:55
返信有難うございます。
>「プロジェクト - 設定 - リンク」の「オブジェクト/ライブラリモジュール」
全ての設定対象におきましてlibjpeg.lib(jpeg-6bのソースからlibを作成)
を書き込んでいます。

せんべえ 2003/10/30(木) 18:47:40
そのlibはプロジェクトの中とProgram Filesm⇒ 
Microsoft Visual Studio⇒ VC98⇒ Libのフォルダの中に設置しています。

SunPac 2003/10/30(木) 18:55:00
> ツール − オプション − ディレクトリ
> だと思われます。

その通りです、すみません。
で、ヘッターファイルはどこにあるのでしょう?
プログラムと同じフォルダに入れて、

   #include "jpeglib.h"

で試してみては。
ヘッダーファイルもディレクトリの設定しなきゃダメですので。

せんべえ 2003/10/30(木) 18:57:50
返信有難うございました。
>プログラムと同じフォルダに入れ
はい。同じプロジェクトフォルダの中に入れております。
jpeg-6bの全てのヘッダファイルを入れています。

せんべえ 2003/10/30(木) 19:08:08
>ヘッダーファイルもディレクトリの設定しなきゃダメですので。
すいません。
申し訳ないです。ここが良く分かりませんでした。
私はheader filesを右クリックしその中にjpeg-6bの全てのヘッダファイルを入れていま
す。それだけではいけないですか?
もしディレクトリの設定が必要であればどこを直せばいいですか?

sugar 2003/10/30(木) 19:17:56
ツール − オプション − ディレクトリ

です。

「表示するディレクトリ」コンボボックスがインクルードファイルの時に
表示されるパスの一覧のどれかに、jpeg関連のヘッダファイルがあればいいはず。
または、jpeg関連のヘッダファイルがあるパスを一覧に登録してもOK。

あと、このコンボボックスにはライブラリファイルと言うのがあります。
この時に表示されるディレクトリの一覧のどれかに、
libjpeg.libは置かれてますか?
逆にlibjpeg.libがあるパスを一覧に登録してもOK。

せんべえ 2003/10/30(木) 19:40:23
>この時に表示されるディレクトリの一覧のどれかに、
>ibjpeg.libは置かれてますか?
はい。Program Filesm⇒ 
Microsoft Visual Studio⇒ VC98⇒ Libのフォルダの中に設置しています。

せんべえ 2003/10/30(木) 20:07:53
>表示されるパスの一覧のどれかに、jpeg関連のヘッダファイルがあればいいはず。
>または、jpeg関連のヘッダファイルがあるパスを一覧に登録してもOK。
両者も試してみましたが変わりないです。

sugar 2003/10/30(木) 20:30:29
パス関係は問題ないってことですかねぇ。

ところでせんべえさんのプログラム、MFCですか?
それともSDKですか?

既にどれほど作りこまれてるのかわかりませんが、
一度、シンプルな最小プログラムにjpegライブラリを組み込めるか
試してみてはどうでしょう。

せんべえ 2003/10/30(木) 20:48:20
返信有難うございます。
>パス関係は問題ないってことですかねぇ。
皆様の助言を踏まえたうえ、現状ではそのようにかんがえます。

>ところでせんべえさんのプログラム、MFCですか?
>それともSDKですか?

私は下記のページを参考にしています。
http://www.asahi-net.or.jp/~yw3t-trns/opengl/samples/imgsavejpeg/index.htm

sugar 2003/10/31(金) 09:53:46
URLところからサンプルをダウンロードしてみました。
せんべえさんが遭遇したリンクエラーは出なかったのですが、
ビルドはうまくいきませんでした(LNK2005が発生)。

でも、ちょっと気づいたことが。
libjpeg.lib をビルドした時のコンパイルオプションなんですが、
「プロジェクトの設定」ダイアログのC/C++タブのカテゴリコンボボックスから
「コード生成」を選び、使用するランタイムライブラリ コンボボックスを見てくださ
い。
私の場合、libjpeg.libは「マルチスレッド(DLL)」になっていたのに対し、
imgsave(DLしたサンプル)は「シングルスレッド*」になってまして、
これを前者に統一したらビルドできるようになりました。

せんべえ 2003/10/31(金) 10:16:01
sugarさん
返信有難うございます。
どうしてでしょうか??
昨夜もずっと行っていましたが解決しないままです。とほほ。
>コード生成」を選び、使用するランタイムライブラリ コンボボックスを見てくださ
い。
確認しました。私のほうはシングルスレッドになっています。
imgsave(DLしたサンプル)を実行するまでの手順をお話しします。
1.jpeg-6bをダウンロードし、http://tanack.hp.infoseek.co.jp/libjpeg.html
このページに書かれている手順に従いVC++でコンパイルし、libjpeg.libを作成。
2.作成したlibjpeg.libをimgsave(DLしたサンプル)のプロジェクトのなかにおき、
実行。
3.リンクの設定などは皆様のアドバイスに従い設定。
このような感じになっています。
なにか気がつくことがありましたらアドバイスをいただけませんか?
お手数おかけします。

sugar 2003/10/31(金) 12:05:23
> 私のほうはシングルスレッドになっています。
>
ライブラリもサンプルアプリケーションも、
一度マルチの方でビルドしなおしてみる価値はありませんかね?
一応、私の方ではマルチで動いている実績があるものですから…。

せんべえ 2003/10/31(金) 12:52:04
>一度マルチの方でビルドしなおしてみる価値はありませんかね?
行ってみましたが同じ結果です。
私の上記の手順は大丈夫ですか?
sugarさんと違うところはありましたか?
よろしければ教えてください。

sugar 2003/10/31(金) 14:30:04
私の場合は、libjpeg.libは既に持ってたので、今回新たにビルドはしてません。
このビルドの際にせんべえさんが参考にしたというサイトですが、
ファイル拡張子を *.c から *.cpp に変更してますね。
私がlibjpeg.libを作った時は、*.c のままです。
このあたり、関係してくるのかな?

imgsaveはC++ではなくCのプログラムなので、もしかしたら…?

せんべえ 2003/10/31(金) 14:34:43
>imgsaveはC++ではなくCのプログラムなので、もしかしたら…?
sugarさん何度も有難うございます。
物凄い参考になりました。
再度ライブラリを作ってみることにします。

tetrapod 2003/10/31(金) 15:05:46
提示の Web Page のコンパイル手順はずいぶん乱暴ですね。
IJG のコードを可能な限り尊重すべきだと思います。

MFC 配下で使うのであればマルチスレッドが必須なので
・jmorecfg.h の RGB->BRG 順の変更
・makefile.vc の CFLAG= 行に -MT を追加
の2点だけに絞るべきです。他の変更は不要。
んでコマンドプロンプトから nmake -f makefile.vc でライブラリ作成。

んで、自作コードのほうは
extern "C" {
#include "jpeglib.h"
}
とすべきでしょう。

せんべえ 2003/10/31(金) 15:13:18
返信有難うございました。
現在も解決しないままです。
私も原因が作成したライブラリのような気がします。
そこで、tetrapod さんのアドバイスも参考にさせていただきたいのですが
自作コードのところが良く分かりません。
もしよろしければご教授ください。

せんべえ 2003/10/31(金) 15:27:09
1.jmorecfg.h の RGB->BRG 順の変更⇒ここはいまいちよく分からず
上記のページの変更のままです。
これはどういった意味でしょうか?
2.CFLAGS= $(cflags) $(cdebug) $(cvars) -I-MT. で変更を行いました。

以上を変更してDOSでコマンドを打ち込みましたが以下のような結果になりました。
'nmake' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
make -f makefile.vc 
makefile.vc:12: *** missing separator.  Stop.

tetrapod 2003/10/31(金) 15:47:09
コマンドラインから VC++ を使う方法はご存知でしょうか?
VC98\BIN ディレクトリに vcvars32.bat が生成されているので、
開いたコマンドライン窓中からこれを実行すると
PATH 等環境変数がセットされます。そのあとでなら
nmake が使えるはず。

unix-like make (GNU make) と Microsoft NMAKE は
似て非なるものなので nmake 用 makefile を gnu make で
使うことはできません。

ということで試してみてください。

RGB->BRG 順の変更とは jmorecfg.h の RGB_RED のところの変更。
makefile.vc の -MT 追加
他は IJG の配布ファイルのままでライブラリのコンパイルは
通りました。そのライブラリを使うとこまでは試してませんが...

tetrapod 2003/10/31(金) 16:25:04
おっと見落とし
-I-MT. 
とマジに書いたのなら間違い。
-I. -MT
としなければなりません。マニュアル読むべし。

せんべえ 2003/10/31(金) 16:36:59
tetrapodさんできました!!
感謝感激です。
有難うございます。
最後に聞きたいのですが
>自作コードのほうは
>extern "C" {
>#include "jpeglib.h"
>}
上記のコードは何ですか?
私は実行しなかったです。
物凄く気になるのでよろしければ教えてください。

tetrapod 2003/10/31(金) 17:09:34
えーと、チェーンが長くて情報が分散しているのでちょっとまとめてみました。

MFC を使ったアプリケーションで libjpeg.lib を使おう!

1.ライブラリの構築
http://tanack.hp.infoseek.co.jp/libjpeg.html
の手順そのままは個人的にはお勧めしません。
少なくとも cpp にリネームする項目だけは避けて欲しい。
ライブラリ構築は IJG の配布したものに最低限の修正だけで行うべし。
1-a.jmorecfg.h の修正を行う (RGB->BRG 対応のみ) 。
1-b1.makefile.vc の修正を行う
CFLAGS= の行の末尾に -MD を追加し、ライブラリ構築。
これで出来たライブラリを libjpeg.lib としてどこかにコピー。
1-b2.makefile.vc の修正を行う2
CFLAGS= の末尾の -MD を -MDd にしてライブラリ再構築
これで出来たライブラリを libjpegd.lib としてどこかにコピー。

2.libjpeg.h の MFC 対応
上記 webpage の jconfig.h 修正分を当てるとOK。

3.MFC プロジェクトの設定
ライブラリの追加・ヘッダパスの追加を行う。このとき
デバッグ構成のほうは libjpegd.lib を追加し
リリース構成のほうは libjpeg.lib を追加する
と、リンク時警告が出なくてGOOD。

4.MFC プロジェクトソースの設定
jpeg を扱う cpp ソースコードには
extern "C" {
#include "jpeglib.h" 
}
を追加。追加個数が多いようなら stdafx.h に追加。

かな?だれぞフォローお願い。

tetrapod 2003/10/31(金) 17:17:48
extern "C" なしでリンク成功ということは、
せんべいさんのところでは .c を .cpp にリネームして libjpeg.lib を
構築し、そのライブラリを使ったはずです。そうでないと必ずエラーになります。
今お使いのその libjpeg.lib は C ソースから呼べなくなっています。
一度上記に書いた手順でもう一度ライブラリ構築してみてください。

extern "C" はまあ、おまじないというかなんと言うか。
C++ ソースコードから C で作った関数を呼ぶときに必要
C++ ソースコード中に C から呼べる関数を作るときに必要
な,おまじないです。
詳細は name mangling などで検索掛けてみてください。

jpeglib は C のソースコードなので MFC アプリのような C++ ソース
から C 関数を呼びたい訳で extern "C" は必須です。

先の発言では -MT と書いちゃいましたが MFC 前提ということなら -MD の
方が正しいです。で、リンク時に警告が出るので -MD と -MDd を使い分ける
のが適切です。

せんべえ 2003/10/31(金) 18:18:02
[[解決]]
いろいろとアドバイス有難うございました。
本当に感謝感激です。

>extern "C" なしでリンク成功
おっしゃるとおりでした。
>-MT の件
2.CFLAGS= $(cflags) $(cdebug) $(cvars) -I-MT
このままでもコンパイルができました。
そしてそのライブラリを用いてimgsave(DLしたサンプル)を実行できます。
これはとても不思議です。

PATIO 2003/10/31(金) 18:21:39
extern "C"で囲むと言うのは、
関数のエクスポート名の命名規約をCで行うと言う意味です。

Cにはクラスとか関数の多重定義と言う機能が無いので関数をライブラリの外部から
参照するときの名前とコーディング上の関数名の記述がほとんど同じなんですが、
C++だと上記の概念があるので関数名に色々と修飾が付きます。
ソースの拡張子をcppに替えてしまうとC++のソースとしてコンパイルされてしまうので
関数のエクスポート名がC++の命名規約を使って行われてしまい、
Cのつもりで表記していると名称があわないためにリンクで失敗します。
C++のソース扱いでコンパイルしているときにその関数の命名規約を強制的に
Cのもので行うためにextern "C"を使用します。

VCのHELPにこの辺の話が載っていたと思います。
extern "C"に関連する項目から探してみてはいかがでしょうか?

古いスレッドには追加発言できません。