libpng及びzlibをマルチスレッド版スタティックリンクライブラリとしてVC6.0でビルドしまし
た。
これらを使ってbmpをpngにするActiveXをATL COM Wizzardで書いてみたのですが、リンク時に
libpng125.lib(pngwrite.obj) : error LNK2001: 外部シンボル _deflate@8 は未解決です
libpng125.lib(pngwutil.obj) : error LNK2001: 外部シンボル _deflate@8 は未解決です
libpng125.lib(pngwrite.obj) : error LNK2001: 外部シンボル _deflateEnd@4 は未解決で
す
libpng125.lib(png.obj) : error LNK2001: 外部シンボル _crc32@12 は未解決です
libpng125.lib(png.obj) : error LNK2001: 外部シンボル _inflateReset@4 は未解決です
libpng125.lib(pngwutil.obj) : error LNK2001: 外部シンボル _deflateInit2_@32 は未
解決です
libpng125.lib(pngwutil.obj) : error LNK2001: 外部シンボル _deflateReset@4 は未解
決です
となってしまいます。
何がいけないのかご教示いただけないでしょうか?
ちなみに、自分でビルドしたzlibではなくどこかのサイトに転がっていたzlibstat.lib
というのを使うと、上記エラーはでないのですが、
LINK : warning LNK4098: defaultlib LIBC は他のライブラリの使用と競合していま
す; /NODEFAULTLIB:library を使用してください
となってしまいます。
以上宜しくお願い致します。
libpngは内部でzlibの関数を呼んでいるので,
zlibもビルドして,リンクする必要があります。
あるいは、libpngのビルド時にzlibも一緒にリンクしてもいいですが。
>LINK : warning LNK4098: defaultlib LIBC は他のライブラリの使用と競合していま
>す; /NODEFAULTLIB:library を使用してください
これは、使用しているランタイムライブラリ(シングルスレッド・マルチスレッド)
がライブラリと,アプリケーション本体で違うのが原因だと思われます。
アプリのスレッドモデルと、ライブラリのスレッドモデルは、合わせるのが原則です。
まあ、無視しても動く場合もありますが、あまりおすすめしません。
すいません。よく読んでませんでした。zlibもリンクしているのですね。なぜでしょう。
とりあえず見つからないのは,zlibの関数のようですが。
kojimaさんレスありがとうございます。
最初のレス(リンカの警告の部分)については、おっしゃる通りでそれゆでにzlibを
マルチスレッド版として自分でビルドしてみたわけです。最初はzlibstat.lib
を使っていて/NODEFAULTLIBでしのいでいたのですが、プログラムが完成したので
LIBC問題の解決のために独自にzlibをビルドしたら別の問題が出たというのが
事の経過です。
ちなみに、_deflate@8とかcrc32@12とかってC++でコンパイルするときの内部名
じゃなかと思っています。libpngもzlibもソースの拡張子は.cですのでC++と
誤認されるはずはないのですが...
ひろってきたzlibstat.libでは(LIBC問題はありますが)リンクできるので、
zlibのビルドの仕方が悪いように思うのですが、色々設定を変えてビルドしても
状況がかわらないんです。それで助けを求めている次第です。
とりあえずこっちでテストしたところまともに動くようです。
# コンパイル/リンクに通っただけしかチェックしてません。
マルチスレッド・スタティックとするために、コンパイルオプション
-MT -D_MT を libpng/zlib の両方に指定するようにしただけですが。
そうして作った libpng.lib を dumpbin /all libpng.lib したところ
_deflate や _deflateEnd を参照してます。
_deflate@8 や _deflateEnd@4 は参照していません。
libpng の再構築方法に誤りがあると思われます。
こっちで取った libpng-1.2.5 の構築手順
1.copy scripts\makefile.vcawin32 makefile
2.makefile の CFLAGS= 行に -MT -D_MT を追加
同じく -I オプションのディレクトリを修正
3.nmake
こっちで取った zlib-1.1.4 の構築手順
1.copy nt\makefile.nt makefile
2.makefile の dll 作成部分を lib 作成に変更
zlib.lib: $(OBJ1) $(OBJ2)
lib -out:$@ $(OBJ1) $(OBJ2)
に修正
3.makefile 中のコンパイルオプション
$(cvarsdll) を $(cvarsmt) に全置換
ATL COM の関係で必要なコンパイルオプション等あれば要追加変更かな?
tetrapodさん、レス有難うございます。
dumpbinを自分のlibpng.libに適用したところ、libpng.libが
_deflate@8 や _deflateEnd@4を参照するようになっておりました。
でも、VCでlibpngをコンパイルすると、(自分なりに色々やってみた範囲では)
どうやってもこうなってしまいます。
当方の都合上、nmakeではなくなるべくVCで処理したいと考えていますが、
良い方法をご存知の方がいらっしゃいましたら、ご教示のほど宜しくお願い致します。
ちなみに、現在のlibpngのコンパイルオプションは、
/nologo /MT /W3 /GX /O2 /D WIN32 /D NDEBUG /D _WINDOWS /D _MBCS /D PNG_
USER_MEM_SUPPORTED /D _WIN32_WCE /FpRelease/libpng125.pch /YX /FoRelease/
/FdRelease/ /FD /c
です。(tetrapodさんは-D_MTを指定されていますがこれって必須ですか?)
まずいところがあれば、ご教示のほど宜しくお願い致します。
zconf.h/zlib.h をきっちり読めばわかります (で終わっても良いのですが)
_deflate が _deflate@8 に修飾されるのは __stdcall なときです。
zconf.h によれば __stdcall つまり WINAPI 修飾子が使われるのは
-DZLIB_DLL がなされているときです。
今回は静的リンクしたいので ZLIB_DLL は定義されていてはなりません。
で、ふつーにコンパイル/リンクすると定義されないはずです。
っていうか libpng をコンパイルするときに使った zconf.h/zlib.h は
正しいものですか?どこかからか変なのもってきてませんか?
zlib-1.1.4 に付属のものと比較してみてください。
違っているようなら入れ替え。
libpngの作り方が悪いとしたら、なんで拾ってきたzlibstat.libでリンクできるのか?
と思い、zlibstat.libをdumpbinしてみたところ、このzlibはなんと、中身が_deflate@8
や_deflateEnd@4という形になっていました。
tetrapodさんの指摘とこの結果から、libpngとzlibのどちらの作り方が
悪いのかについては一意ではないように思います。つまり、現状の私のlibpng
にあったzlibの作り方もあるし、現状の私のzlibにあったlibpngの作り方
があるのではないかということです。
しかしながら、VCでビルドするという前提においてその方法はどちらも私には分かりません。
どなたか助けてくださいまし~。
微妙な差でtetrapodのフォローと入れ違いになってしまいました。
上記のはtetrapodさんの2回目のレスを読んで書いたものではありません。
で、2回目のレスについてですが、zlibのソースはビルド済みのzlibstat.libと
一緒に拾ってきたソースだったような気がします。もしかしたら、ご指摘の通り
正式なソースではないモディファイドバージョンかもしれません。
再度ソースを入手しチェックします。
tetrapodさんのご指摘の通り、zconf.hが公式サイトのものと違っていました。
さっきまで使っていたzconfはZLIB_DLLが未定義なら定義してしまうコードが
入っておりました。tetrapodさん、スゴイご指摘ありがとうございました。
で、日付は同じでしたがzlib.hもついでに公式なものに置き換えて再ビルドしてみました。
ですが、状況はかわりませんでした;_;
なぜでしょう?
zlib.h, zconf.h, png.h, pngconf.h全て確認しましたが、ZLIB_DLLは定義されていません
し、-DZLIB_DLLもやってません。
ちなみに、プロジェクト→設定→C/C++→コード生成は、_cdecl*にしてあります。
状況が変わらないとはやはり _deflate@8 を呼んでいる、の意味?
libpng, zlib 両方を再構築しましたか?
リンクに指定しているライブラリは以前に生成したライブラリの
コピーだったりしていませんか?
困ったときには cl -P -C を試しましょう。
結局のところ、使うほうと使われるほうで呼び出し規約が一致していれば
それが __stdcall だろうが __cdecl だろうが問題ないので、
どちらでも良いから、統一するだけのことです。
解決しました。
いかがわしいzconf.hが、デスクトップとlibpngのフォルダの両方に存在している状況で、
libpng内のものを正しいものに置き換えてビルドしてもダメだったのですが、
デスクトップに存在しているzconf.hを削除したらなぜかうまくコンパイルできました。
#なぜでしょうか...
なにはともあれ無事解決できました。
tetrapodさん、本当に有難うございました。
今回はとても自力では解決できる話ではありませんでしたので、
本当に助かりました。
重ね重ねお礼を申し上げる次第です。