dll の下位互換性を維持したいのですが、Pimpl パターンにはクラス全体をエクスポートする必要があるため、名前マングリングによりさまざまなコンパイラがサポートされません。このような場合、次のように C 互換インターフェイスを一緒に提供できますか? ?
パブリックヘッドで:
#ifdef CPPDYNAMICLINKLIBRARY_EXPORTS
# define SYMBOL_DECLSPEC __declspec(dllexport)
# define SYMBOL_DEF
#else
# define SYMBOL_DECLSPEC __declspec(dllimport)
# define SYMBOL_DEF __declspec(dllimport)
#endif
#ifdef _WIN32
#define GRAPHICAPI __stdcall
#else
#define GRAPHICAPI
#endif
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endif // __cplusplus
#ifdef __cplusplus
namespace myapi{
struct SYMBOL_DECLSPEC Graphics{
Graphics();
~Graphics();
void drawLine(int,int,int,int);
void drawLine(Point,Point);
private:
struct Impl;
const Impl* impl;
}
}//end of myapi
#endif // __cplusplus
struct Graphics;
typedef struct Graphics *PGraphics;
#ifdef __cplusplus
extern "C" {
#endif
SYMBOL_DEF PGraphics GRAPHICAPI newGraphics();
SYMBOL_DEF void GRAPHICAPI deleteGraphics(PGraphics);
SYMBOL_DEF int GRAPHICAPI Graphics_drawLine4(PGraphics,int,int,int,int);
SYMBOL_DEF int GRAPHICAPI Graphics_drawLine2(PGraphics,Point,Point);
#ifdef __cplusplus
}
#endif
また、dll プロジェクトでは、def ファイルに次の定義がありました。
exports
newGraphics @1
deleteGraphics @2
Graphics_drawLine4 @3
Graphics_drawLine2 @4
def ファイルで序数を指定しなかった場合、Graphics_drawArc などの新しい関数を追加すると、関数 Graphics_drawArc が Graphics_drawLine4 の前にエクスポートされ、古いアプリの呼び出し Graphics_drawLine4 が Graphics_drawArc を実際に呼び出し、結果としてクラッシュします。
上記の解決策は正しいですか?