2011-02-05 7 views
0

背景私はネイティブC++、混合C++/CLI、および安全なCで構成されるプロジェクトを構築するために、コマンドラインからCLLINKを使用していますLTCGは、O2はコンパイル時に指定された/ことを覚えていない

++/CLI。 .NET Framework 2.0-3.5をターゲットにする必要があります(VC20ツールチェーンを使用していますが、VS2010をインストールしていますが、Windows 7と.NET 3.5 SP1用にVS2008 C++ ExpressとSDKをインストールしてください)。

VS100ツールチェーンを使用してスクリプトを試すとうまくいきますが、.NET v4.0をターゲットにしています。自分のネイティブコードと混合コードに/GLを使用しないと動作します。私はこれらの解決策を知っているので、提案しないでください。なぜこれが起こっているのか理解しようとしています。

問題

私はネイティブコードで、次の警告の多くを取得/GL/LTCGを使用する場合:警告C4748::(###)

xxx.cpp /GSができません関数内で最適化が無効になるため、パラメータとローカル変数をローカルバッファオーバーランから保護します。

C:混合コードのエラーエラーC4801:\プログラムファイル(x86の)マイクロソフトのVisual Studio 9.0 \ VCの\ \は\ vcclr.h(47)を含み、参照することによってリターンを検証することはできません:返されるの定義地元の二つ目は、あなたがconst wchar_t*としてString^を使用することができますし、インライン化されなければならない(とインラインマークされている)の関数であるマイクロソフトのヘッダファイルからPtrToStringCharsためである基本ブロックに

が見つかりません。インライン展開されている場合、「参照による戻り値」は実際には戻り値ではないため、エラーは発生しません。

問題は、コンパイル時に最適化を使用していることです。最高レベルのインライン展開(/Ob2)を持つ標準/O2を使用し、通常は/GSを使用します。ここで

スクリプト

は私の要約コンパイルスクリプト

set TARGET=x86 
call "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat" %TARGET% 

set CL=/nologo /Zl /Zi /W4 /O2 /Oy- /GL /GS /EHa /MP /D NDEBUG /D _UNICODE /D UNICODE /D INTEGRATED /Fdout\ /Foout\ 
set LINK=/nologo /LTCG /CLRIMAGETYPE:IJW /MACHINE:%TARGET% /SUBSYSTEM:WINDOWS,6.0 /OPT:REF /OPT:ICF /DEFAULTLIB:msvcrt.lib /DEFAULTLIB:msvcmrt.lib 
set CSC=/nologo /w:4 /d:INTEGRATED /o+ /target:module 

set CL_NATIVE=/c /FI"stdafx-native.h" 
set CL_MIXED=/c /clr /LN /FI"stdafx-mixed.h" 
set CL_PURE=/c /clr:safe /LN /GL /FI"stdafx-pure.h" 

set NATIVE=a.cpp b.cpp ... 
set MIXED=c.cpp d.cpp ... 
set PURE=e.cpp f.cpp ... 

cl %CL_NATIVE% %NATIVE% 
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% 

cl %CL_MIXED% %MIXED% 
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% 

cl %CL_PURE% %PURE% 
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% 

link /LTCG /NOASSEMBLY /DLL /OUT:"out\x.netmodule" out\*.obj 
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% 

答えて

2

ショートバージョンです:コード検証がアクセシビリティチェックを実行した後、MSILでインライン化は、JITの間に行われます。

ロングバージョン:MSILは常にコンパイル単位全体、さらにはアセンブリ全体で最適化されますので(最適化がデバッグではオフになっている場合を除き)

プログラム全体の最適化は、MSILには適用されません。私はこれがあなたの警告の源だと思う。

多くの最適化は、インライン展開を含むJITの責任です。アクセシビリティチェックと組み合わせることで、C++コンパイラはMSIL上でインライン展開を実行できなくなります。 (プライベートメンバーを使用するメンバ関数がネイティブC++でインライン展開されるとどうなりますか?プライベートメンバーを使用しているメンバー関数がMSILでそのプライベートメンバーにアクセスできない関数にインライン化するとどうなりますか? .NETランタイムは絶対に適合します。インライン展開のコンパイラ設定について知っていると思うものはすべてMSILには当てはまりません)。

... PtrToStringCharsの使用は、検証不可能なので/clr:safeと互換性がありません。どちらも検証可能なアセンブリを作成しようとしないので、/clrで、そして/clr:pureでも問題ありません。前述のように、コンパイラは/clrモードでコンパイルするときにインライン化することはできません。これがエラーの原因です。

最終的な問題は、ネットモジュールの作成です。私は、混合モードのコードをネットモジュールではなく、本格的なアセンブリとして作成しなければならないと確信しています。

+0

'PtrToStringChars'は、'/clr:safe'とネイティブコードとの間のinteropとして '混在している'コードで使用されます。これは 'stdafx-mixed.h'ヘッダーにのみ含まれています。これは '/ clr'でコンパイルされます。私はリンカに '/ clr'('/CLRIMAGETYPE:IJW')を使うよう伝えます。 – coderforlife

+0

'netmodule'のことです。それは可能であるはずです(私は部分的に動作するようにしました)。 [C#アプリケーションへのネイティブC++のリンク](http://blogs.msdn.com/b/texblog/archive/2007/04/05/linking-native-c-into-c-applications.aspx)を参照してください。ゴール。 – coderforlife

+0

@thiamin:ブログ記事の内容をより詳細に検討してください。ネイティブコードは決してネットモジュールで終わることはありません。むしろ、C#ネットモジュールはC++リンカによって取り込まれ、単一の混合モードPEを作成します。しかし、あなたはまだコンパイルに失敗しているので、まだリンクにはいません。/GLと/ GSをネイティブのコンパイルオプションに移動してみてください。マネージコードをコンパイルするときには利点がありません。 –

関連する問題