Windows では、PL/I コンパイラーは、OPTLINK、CDECL、および STDCALL という 3 つの 主なリンケージをサポートします。Windows では、すべてのシステム・サービスが STDCALL リンケージ を使用します。
これらのリンケージは、パラメーター引き渡し規則が異なります。
PL/I for Windows コンパイラーは、SYSTEM リンケージが指定されると、STDCALL リンケージが指定されたかのように解釈します。VisualAge C コンパイラーも 同じように解釈します。
Windows では、すべての外部名が装飾されます。外部属性が名前を指定しない場合、名前の装飾はリンケージによって異なります。
これらの名前装飾によって、ルーチンの呼び出し側が、そのルーチンの誤ったリンケージを 指定すると、プログラムはリンクに失敗することになります。
ここまでの名前装飾の説明は、外部属性が名前を指定しなかったルーチンについての説明でした。 この説明は、外部属性が、宣言された名前と大/小文字のみが異なる名前を指定した場合についても当てはまります。 このような場合は、外部属性の一部として指定された名前が装飾されます。
例えば、次の宣言の場合、リンカーには ?getenv という名前が見えます。
dcl getenv ext('getenv')
entry( char(*) varz byaddr nonasgn )
returns( pointer )
options( nodescriptor linkage(optlink) );
同じように、次の宣言では (DLL をロードする Windows システム・ルーチンの場合)、外部属性の一部として指定された名前は装飾され、リンカーには _LoadLibraryA@4 という名前が見えます。
dcl loadlibrarya ext('LoadLibraryA')
entry( char(*) varz byaddr nonasgn )
returns( pointer byvalue )
options( linkage(stdcall) nodescriptor );
ただし、名前が外部属性の一部として指定され、その名前が、大/小文字以外に宣言された名前と 異なる場合、名前の装飾は行われません。
例えば、次の宣言の場合、名前の装飾は行われず、リンカーには ?getenv という名前が見えます。
dcl getenv ext('?getenv')
entry( char(*) varz byaddr nonasgn )
returns( pointer )
options( nodescriptor linkage(optlink) );
この最後の例に示したように、名前装飾をユーザー自身が実行すると、通常、コードは移植しにくいものになります。 例えば、Windows および AIX の場合、これまでの例では、getenv の最初の宣言のみが有効です。