PGDLLEXPORT覚書

放っておくと忘れてしまうので覚書。
最近PGDLLEXPORTというマクロが導入され、たとえばsrc/include/fmgr.h内の次のマクロ定義に使用されている。


#define PG_MODULE_MAGIC \
extern PGDLLEXPORT const Pg_magic_struct *PG_MAGIC_FUNCTION_NAME(void); \
const Pg_magic_struct * \
PG_MAGIC_FUNCTION_NAME(void) \
{ \
static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA; \
return &Pg_magic_data; \
} \
extern int no_such_variable


ここでPGDLLEXPORTは関数PG_MAGIC_FUNCTION_NAMEがdll(もしくはexe)から何らかの形でexportされるべき対象であることを示し、ソースレベルでexport指定可能なWindows環境(MSVC、mingwまたはcygwin)下では実際に__declspec(dllexport)に置き換えられる....予定であったのだがmingwで(cygwinでも?)不具合を引き起こし、現状はMSVC環境でのみ__declspec(dllexport)指定が残っている。


問題点は二つ。

1.mingw及びcygwin下での対応の仕方。__declspec(dllexport)が駄目ならということで何故か__declspec(dllimport)に置き換えられている。これは基本的に間違いである。__declspec(dllimport)で実体はモジュールの外にあると宣言した直後に関数の実装本体が続くのだから全く奇妙なマクロ定義というしかない。__declspec(dllexport)がどうしても駄目なら__declspec宣言そのものをなくすべきであろう。

2.そもそもなぜmingw(cygwin?)下で不具合が発生するのかということ。
dllをbuildするために利用しているdllwrap(dlltoolも?)と__declspec(dllexport)の相性が悪いこと。具体的にいうとDLLのrelocセクションに重複が発生してしまい実際にrelocateが発生した場合にクラッシュを引き起こしてしまう。これに関してはdllwrapでなくgccを利用すれば解決可能である。