1

私が調べた限りでは、GNUCはデフォルトで関数呼び出しにcdeclを使用していることがわかります。VST SDKは、GNU Cでコンパイルするときに、呼び出しをcdeclとして明示的に定義し、次のエラーを吐き出します。

again.cpp:27:15: warning: multi-character character constant [-Wmultichar]
In file included from /code/vstsdk2.4/public.sdk/source/vst2.x/audioeffect.h:16:0,
             from /code/vstsdk2.4/public.sdk/source/vst2.x/audioeffectx.h:17,
             from again.h:16,
             from again.cpp:13:
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:125:32: error: expected ')' before '*' token
In file included from /code/vstsdk2.4/public.sdk/source/vst2.x/audioeffect.h:16:0,
             from /code/vstsdk2.4/public.sdk/source/vst2.x/audioeffectx.h:17,
             from again.h:16,
             from again.cpp:13:
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:126:32: error: expected ')' before '*' token
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:127:27: error: expected ')' before '*' token
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:128:27: error: expected ')' before '*' token
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:129:27: error: expected ')' before '*' token
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:130:28: error: expected ')' before '*' token
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:149:2: error: 'AEffectDispatcherProc' does not name a type
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:152:2: error: 'AEffectProcessProc' does not name a type
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:155:2: error: 'AEffectSetParameterProc' does not name a type
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:158:2: error: 'AEffectGetParameterProc' does not name a type
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:183:2: error: 'AEffectProcessProc' does not name a type
/code/vstsdk2.4/pluginterfaces/vst2.x/aeffect.h:187:2: error: 'AEffectProcessDoubleProc' does not name a type
In file included from /code/vstsdk2.4/public.sdk/source/vst2.x/audioeffectx.h:17:0,
             from again.h:16,
             from again.cpp:13:
/code/vstsdk2.4/public.sdk/source/vst2.x/audioeffect.h:27:35: error: expected ')' before 'audioMaster'
In file included from /code/vstsdk2.4/public.sdk/source/vst2.x/audioeffectx.h:17:0,
             from again.h:16,
             from again.cpp:13:
/code/vstsdk2.4/public.sdk/source/vst2.x/audioeffect.h:155:2: error: 'audioMasterCallback' does not name a type
In file included from again.h:16:0,
             from again.cpp:13:
/code/vstsdk2.4/public.sdk/source/vst2.x/audioeffectx.h:27:36: error: expected ')' before 'audioMaster'
In file included from again.cpp:13:0:
again.h:22:29: error: expected ')' before 'audioMaster'
again.cpp:16:36: error: 'audioMasterCallback' was not declared in this scope
again.cpp:17:1: error: expected ',' or ';' before '{' token
again.cpp:22:14: error: expected constructor, destructor, or type conversion before '(' token
scons: *** [again.os] Error 1
scons: building terminated because of errors.

同時に、明示的な定義__cdeclを削除し、コンパイラーに決定させると、問題なくコンパイルされます。デフォルトはcdeclなので、これで同じエラーがスローされないようにする必要がありますか?

ウィキペディアで、cdeclの場合、「GCCバージョン4.5以降、関数を呼び出すときにスタックを16バイト境界に整列させる必要があります(以前のバージョンでは4バイトの整列のみが必要でした)」と読みました。私の問題の洞察と考えられる原因は?

また、それを__fastcallまたは__stdcallとして定義すると、同じエラーが発生します。では、ここで実際に何が起こっているのでしょうか。

4

2 に答える 2

2

複数のプラットフォームを維持しようとすると面倒になるので、ソースを直接変更しない方が好きです。代わりに-D__cdecl=""、コンパイラフラグを渡して定義します。

このアプローチを使用してLinux上にいくつかのVSTを構築しましたが、正常に動作します。明示的な__cdeclを定義する(または必要に応じて手動で削除する)だけで安全です。VST SDKは、この意味で少し遅れています。特に、サポートする価値のあるオペレーティングシステムは、MacとWindowsの2つだけであると考えられています。を見るとaeffect.h、次のコードが見つかります。

#if TARGET_API_MAC_CARBON
    #ifdef __LP64__
        #pragma options align=power
    #else
        #pragma options align=mac68k
    #endif
    #define VSTCALLBACK
#elif defined __BORLANDC__
    #pragma -a8
#elif defined(__GNUC__)
    #pragma pack(push,8)
    #define VSTCALLBACK __cdecl
#elif defined(WIN32) || defined(__FLAT__) || defined CBUILDER
    #pragma pack(push)
    #pragma pack(8)
    #define VSTCALLBACK __cdecl
#else
    #define VSTCALLBACK
#endif

したがって、基本的に、これを回避する最善の方法は、__cdeclを定義解除することです。GCCはコードを問題なくコンパイルする必要があります。

于 2012-05-29T07:13:10.663 に答える
0

私は C++ があまり得意ではないので、いろいろ調べた結果、その理由がわかりました。これ__cdeclは Microsoft Visual C++ の拡張で__attribute__((cdecl))あり、関数宣言の最後と同様に GNU C で実装できます。

Microsoft VC++ アプローチ:

void __cdecl MyFunction(int, int);

GNU C++ アプローチ:

void MyFunction(int, int) __attribute__((cdecl));

上記のどれも標準 C++ の一部ではありません。

cdecl が G++ のデフォルトの呼び出し方法であるため、VSTCALLBACK を何も設定しないと機能します。

スタインバーグのプログラマーが、G++ で実装された VC++ アプローチのインスタンスを 1 つも見つけられないため、なぜこのように定義したのかわかりません。実際、Mac OSX (g++ コンパイラのバージョンは 4.2.1、Linux では 4.6.3) の場合、VSTCALLBACK が __cdecl に設定されていると、同様の方法で失敗します。

于 2012-05-30T10:43:58.270 に答える