続 CRTPと__declspec(dllexport)
iterator_facadeにも同じ問題を見つけたので、iterator_facadeを使った反復子をdllexportしている箇所を調べてみたところ、Boost.Signalsにありました。
#if BOOST_WORKAROUND(_MSC_VER, <= 1400) void decrement(); void advance(difference_type); #endif
#if BOOST_WORKAROUND(_MSC_VER, <= 1400) void named_slot_map_iterator::decrement() { assert(false); } void named_slot_map_iterator::advance(difference_type) { assert(false); } #endif
http://lists.boost.org/boost-users/2005/08/12982.php
を見る限りVC++のバグという見解のようです。
じゃ、他のコンパイラはエクスポートすべき関数をどう判定してるの?と思い、BorlandのDLLを確認してみます。
C:\Path-to-dir>tdump hamigaki_audio-bcb58-d-0_40.dll | grep vorbis_encoder_base File STDIN: 000187A0 70 0018 hamigaki::audio::detail::vorbis_encoder_base::vorbis_encoder_base() 0001887C 71 0019 hamigaki::audio::detail::vorbis_encoder_base::~vorbis_encoder_base() 00018AAC 74 001A hamigaki::audio::detail::vorbis_encoder_base::close() 000188EC 72 001B hamigaki::audio::detail::vorbis_encoder_base::open(void *, long, long, float, int (*)(void *, const char *, int), void (*)(void *)) 000189D4 73 001C hamigaki::audio::detail::vorbis_encoder_base::open(void *, long, long, const hamigaki::audio::vorbis_encode_params&, int (*)(void *, const char *, int), void (*)(void *)) 00018B84 75 001D hamigaki::audio::detail::vorbis_encoder_base::write_blocks(const float *, int)
あぁ、なるほどwrite_blocks()はエクスポートするけど、write()はエクスポートされないわけですか。write()の実装はarbitrary_positional_facade.hppにインラインで存在するから問題なし、ということですね。
というわけで、Boost.Signalsと同じ対処をしました。
http://hamigaki.sourceforge.jp/hamigaki/iostreams/arbitrary_positional_facade.hpp
ちなみにVC++の場合、
66 41 00005BC0 ?write@vorbis_encoder_base@detail@audio@hamigaki@@QAEH PBDH@Z = ?write@vorbis_encoder_base@detail@audio@hamigaki@@QAEHPBDH@Z (public: i nt __thiscall hamigaki::audio::detail::vorbis_encoder_base::write(char const *,i nt))
write_blocks()でなく、write()をエクスポートしていました。だから、不要なメンバ関数まで実装する必要があったんですね。