方法: /Clr:pure に移行します。How to: Migrate to /clr

このトピックでは、ネイティブ コードをコンパイルするときに発生する問題を説明 /clr (を参照してください/clr (共通言語ランタイムのコンパイル)詳細については)。This topic discusses issues that arise when compiling native code with /clr (see /clr (Common Language Runtime Compilation) for more information). /clrネイティブの C++ コードを呼び出し、その他のネイティブ C++ コードだけでなく、.NET アセンブリから呼び出すことができます。/clr allows native C++ code to invoke and be invoked from .NET assemblies in addition to other native C++ code. 参照してください混在 (ネイティブおよびマネージ) アセンブリネイティブと .NET の相互運用性を使用してコンパイルの利点の詳細についての /clrします。See Mixed (Native and Managed) Assemblies and Native and .NET Interoperability for more information on the advantages of compiling with /clr.

/clr でライブラリ プロジェクトをコンパイルする場合の既知の問題Known Issues Compiling Library Projects with /clr

Visual Studio がライブラリ プロジェクトをコンパイルするときに、既知の問題を含む /clr:Visual Studio contains some known issues when compiling library projects with /clr:

  • コードが実行時に型を照会できますします。Your code may query types at runtime with CRuntimeClass::FromName. ただし、MSIL .dll 内の型がある場合 (でコンパイルされた /clr)、呼び出しFromName(は表示されませんこの問題コードがある後に FromName 呼び出しが発生した場合、マネージ .dll で静的コンス トラクターが実行前に発生した場合に失敗する可能性があります実行されるマネージ .dll で)。However, if a type is in an MSIL .dll (compiled with /clr), the call to FromName may fail if it occurs before the static constructors run in the managed .dll (you will not see this problem if the FromName call happens after code has executed in the managed .dll). この問題を回避するには、マネージド静的コンストラクターを強制的に構築します。それには、マネージド .dll で関数を定義してエクスポートし、その関数をネイティブ MFC アプリケーションから呼び出します。To work around this problem, you can force the construction of the managed static constructor by defining a function in the managed .dll, exporting it, and invoking it from the native MFC application. 例:For example:

    // MFC extension DLL Header file:
    __declspec( dllexport ) void EnsureManagedInitialization () {
       // managed code that won't be optimized away
       System::GC::KeepAlive(System::Int32::MaxValue);
    }
    

Visual C++ でのコンパイルCompile with Visual C++

使用する前に /clrプロジェクト内の任意のモジュールで最初にコンパイルし、ネイティブ プロジェクトを Visual Studio 2010 をリンクします。Before using /clr on any module in your project, first compile and link your native project with Visual Studio 2010.

最も簡単なパスを指定する順番では、その後に、次の手順を /clrコンパイルします。The following steps, followed in order, provide the easiest path to a /clr compilation. これらの手順では、手順ごとにプロジェクトをコンパイルして実行することが重要です。It is important to compile and run your project after each of these steps.

Visual Studio 2003 より前のバージョンVersions Prior to Visual Studio 2003

強化されたに関連するコンパイラ エラーが発生する可能性があります Visual Studio 2003 より前のバージョンから Visual Studio 2010 にアップグレードする場合C++Visual Studio 2003 で標準の準拠If you are upgrading to Visual Studio 2010 from a version prior to Visual Studio 2003, you may see compiler errors related to the enhanced C++ standard conformance in Visual Studio 2003

Visual Studio 2003 からアップグレードします。Upgrading from Visual Studio 2003

せず以前に Visual Studio 2003 で作成されたプロジェクトをコンパイルするときも、まず /clr ANSI/ISO 準拠といくつかの重大な変更に、Visual Studio が今すぐ増加はします。Projects previous built with Visual Studio 2003 should also first be compiled without /clr as Visual Studio now has increased ANSI/ISO compliance and some breaking changes. 最も注意が必要な可能性のある変更はCRT のセキュリティ機能します。The change that is likely to require the most attention is Security Features in the CRT. CRT を使用するコードでは、廃止警告が生成される可能性があります。Code that uses the CRT is very likely to produce deprecation warnings. これらの警告は、抑制しますですが、新しい移行セキュリティが強化されたバージョンの CRT 関数はより強力なセキュリティを提供し、コードのセキュリティの問題を表示することがあります。These warnings can be suppressed, but migrating to the new Security-Enhanced Versions of CRT Functions is preferred, as they provide better security and may reveal security issues in your code.

C++ マネージド拡張からのアップグレードUpgrading from Managed Extensions for C++

Visual Studio 2005 以降で c++ マネージ拡張で記述されたコードはコンパイルされません /clrします。Starting in Visual Studio 2005, code written with Managed Extensions for C++ won't compile under /clr.

C コードから C++ への変換Convert C Code to C++

Visual Studio は C ファイルをコンパイルする必要がありますの C++ への乗り換え、 /clrコンパイルします。Although Visual Studio will compile C files, it is necessary to convert them to C++ for a /clr compilation. 実際のファイル名を変更する必要はありません。使用することができます /Tp (を参照してください/Tc、/Tp、/TC、/TP (ソース ファイル タイプの指定))。C++ ソース コード ファイルが必要な /clr、オブジェクト指向パラダイムを使用するコードをリファクタリングする必要はありません。The actual filename doesn't have to be changed; you can use /Tp (see /Tc, /Tp, /TC, /TP (Specify Source File Type).) Note that although C++ source code files are required for /clr, it is not necessary to re-factor your code to use object-oriented paradigms.

C コードは、C++ ファイルとしてコンパイルするときは変更を必要とする可能性があります。C code is very likely to require changes when compiled as a C++ file. C++ の型保証の規則は厳密なので、型の変換はキャストで明示的に行う必要があります。The C++ type-safety rules are strict, so type conversions must be made explicit with casts. たとえば、malloc は void ポインターを返しますが、キャストによる C では任意の型のポインターに割り当てることができます。For example, malloc returns a void pointer, but can be assigned to a pointer to any type in C with a cast:

int* a = malloc(sizeof(int));   // C code
int* b = (int*)malloc(sizeof(int));   // C++ equivalent

また C++ では関数ポインターの型も厳密に保証されているので、次のような C コードは変更が必要です。Function pointers are also strictly type-safe in C++, so the following C code requires modification. C++ では、関数ポインターの型を定義する typedef を作成し、その後その型を使用して関数ポインターをキャストすることをお勧めします。In C++ it's best to create a typedef that defines the function pointer type, and then use that type to cast function pointers:

NewFunc1 = GetProcAddress( hLib, "Func1" );   // C code
typedef int(*MYPROC)(int);   // C++ equivalent
NewFunc2 = (MYPROC)GetProcAddress( hLib, "Func2" );

また C++ では、関数を参照したり呼び出すには、その前にプロトタイプを作成するか完全に定義する必要があります。C++ also requires that functions either be prototyped or fully defined before they can be referenced or invoked.

C++ のキーワードとなって発生する C コードで使用される識別子 (など仮想新しい削除boolは true。falseなど) 名前を変更する必要があります。Identifiers used in C code that happen to be keywords in C++ (such as virtual, new, delete, bool, true, false, etc.) must be renamed. これは一般的に、単純な検索置換操作だけで行うことができます。This can generally be done with simple search-and-replace operations.

COMObj1->lpVtbl->Method(COMObj, args);  // C code
COMObj2->Method(args);  // C++ equivalent

プロジェクト設定の再構成Reconfigure Project Settings

プロジェクトをコンパイルして Visual Studio 2010 での実行後は、用に新しいプロジェクト構成を作成する必要があります /clr既定の構成を変更するのではなく。After your project compiles and runs in Visual Studio 2010 you should create new project configurations for /clr rather than modifying the default configurations. /clr一部のコンパイラ オプションと互換性がないと、ネイティブまたはマネージとしてプロジェクトをビルドする別の構成を作成することができます。/clr is incompatible with some compiler options and creating separate configurations lets you build your project as native or managed. ときに /clrプロパティ ページ ダイアログ ボックスと互換性のないプロジェクトの設定が選択されている /clrは無効になります (場合、無効なオプションが自動的に復元されないと /clrは後で選択されていません)。When /clr is selected in the property pages dialog box, project settings not compatible with /clr are disabled (and disabled options are not automatically restored if /clr is subsequently unselected).

新しいプロジェクト構成の作成Create New Project Configurations

使用することができます設定のコピー元オプション、新しいプロジェクト構成 ダイアログ ボックス(ビルド > のConfigurationManager > アクティブ ソリューション構成 > 新規)、既存のプロジェクト設定に基づくプロジェクト構成を作成します。You can use Copy Settings From option in the New Project Configuration Dialog Box (Build > Configuration Manager > Active Solution Configuration > New) to create a project configuration based on your existing project settings. これを、デバッグ構成に対して 1 回、リリース構成に対して 1 回実行してください。Do this once for the Debug configuration and once for Release configuration. それ以降の変更を適用できます、 /clr -特定の構成のみ、元のプロジェクト設定はそのままです。Subsequent changes can then be applied to the /clr -specific configurations only, leaving the original project configurations intact.

カスタム ビルド規則を使用するプロジェクトには、特別な注意が必要な場合があります。Projects that use custom build rules may require extra attention.

この手順は、メイクファイルを使用するプロジェクトにとって別の意味があります。This step has different implications for projects that use makefiles. この場合、別のビルド ターゲットを構成するに固有のバージョンで /clrコンパイルは、元のコピーから作成できます。In this case a separate build-target can be configured, or version specific to /clr compilation can be created from a copy of the original.

プロジェクトの設定の変更Change Project Settings

/clr開発環境で次の手順で選択できる/clr (共通言語ランタイムのコンパイル)します。/clr can be selected in the development environment by following the instructions in /clr (Common Language Runtime Compilation). 既に説明したように、この手順によって競合するプロジェクト設定は自動的に無効になります。As mentioned previously, this step will automatically disable conflicting project settings.

注意

マネージ ライブラリまたは web サービス プロジェクトを Visual Studio 2003 からアップグレードする場合、 /Zlに追加されたコンパイラ オプションは、コマンドラインプロパティ ページ。When upgrading a managed library or web service project from Visual Studio 2003, the /Zl compiler option will added to the Command Line property page. これによって LNK2001 が発生します。This will cause LNK2001. 削除 /Zlから、コマンドライン解決するのには、プロパティ ページ。Remove /Zl from the Command Line property page to resolve. 参照してください/Zl (Omit Default Library Name)コンパイラを設定し、ビルド プロパティ詳細についてはします。See /Zl (Omit Default Library Name) and Set compiler and build properties for more information. または、msvcrt.lib および msvcmrt.lib をリンカーに追加追加の依存関係プロパティ。Or, add msvcrt.lib and msvcmrt.lib to the linker's Additional Dependencies property.

メイクファイルでビルドされたプロジェクトでは、互換性のないコンパイラ オプションを後に手動で無効する必要があります /clrが追加されます。For projects built with makefiles, incompatible compiler options must be disabled manually once /clr is added. 参照してください//clr の制約と互換性のないコンパイラ オプションについて /clrします。See //clr Restrictions for information on compiler options that are not compatible with /clr.

プリコンパイル済みヘッダーPrecompiled Headers

プリコンパイル済みヘッダーがサポートされている /clrします。Precompiled headers are supported under /clr. ただし、コンパイルするかどうかのみ、CPP ファイルの一部 /clr (残りをネイティブ コンパイル) いくつかの変更が必要になりますので、プリコンパイル済みヘッダーを使用して生成された /clrものと互換性がありませんなしで生成 /clrします。However, if you only compile some of your CPP files with /clr (compiling the rest as native) some changes will be required because precompiled headers generated with /clr are not compatible with those generated without /clr. この非互換性が原因という事実に /clrを生成し、メタデータが必要です。This incompatibility is due to the fact that /clr generates and requires metadata. コンパイルされたモジュール /clrしないメタデータが含まれていないプリコンパイル済みヘッダーを使用できますしたがってと非 /clrモジュールは、メタデータを含むプリコンパイル済みヘッダー ファイルを使用できません。Modules compiled /clr can therefore not use precompiled headers that don't include metadata, and non /clr modules can't use precompiled header files that do contain meta data.

一部のモジュールがコンパイルされる場所にプロジェクトをコンパイルする最も簡単な方法は、 /clrプリコンパイル済みヘッダーを完全に無効にします。The easiest way to compile a project where some modules are compiled /clr is to disable precompiled headers entirely. (プロジェクトの [プロパティ ページ] ダイアログで C/C++ ノードを開き、[プリコンパイル済みヘッダー] を選択します。(In the project Property Pages dialog, open the C/C++ node, and select Precompiled Headers. 次に、[プリコンパイル済みヘッダーの作成/使用] プロパティを 「プリコンパイル済みヘッダーを使用しない」 に変更します)。Then change the Create/Use Precompiled Headers property to "Not Using Precompiled Headers".)

しかし、特に大きなプロジェクトの場合、プリコンパイル済みヘッダーを使用するとコンパイルの処理速度がかなり短縮されるので、この機能を無効化することはお勧めしません。However, particularly for large projects, precompiled headers provide much better compilation speed, so disabling this feature is not desirable. この場合に設定してください、 /clrと非 /clr別のプリコンパイル済みヘッダーを使用するファイル。In this case it's best to configure the /clr and non /clr files to use separate precompiled headers. これによって 1 つの手順で実行できます複数選択することをコンパイルするのには、モジュール /clrを使用してソリューション エクスプ ローラーグループを右クリックし、プロパティを選択します。This can be done in one step by multi-selecting the modules to be compiled /clr using Solution Explorer, right-clicking on the group, and selecting Properties. 次に、[ファイルを使用して PCH を作成/使用] プロパティと [プリコンパイル済みヘッダー ファイル] プロパティの両方を変更し、それぞれ異なるヘッダー ファイル名と PCH ファイルを使用するように設定します。Then change both the Create/Use PCH Through File and Precompiled Header File properties to use a different header file name and PCH file respectively.

エラーの修正Fixing Errors

使用してコンパイル /clrコンパイラ、リンカー、またはランタイム エラーが発生する可能性があります。Compiling with /clr may result in compiler, linker or runtime errors. このセクションでは、最も一般的な問題について説明します。This section discusses the most common problems.

メタデータのマージMetadata Merge

データ型のバージョンが異なる場合、2 つの型に対して生成されるメタデータが一致しないため、リンカーのエラーが発生することがありますDiffering versions of data types can cause the linker to fail because the metadata generated for the two types doesn't match. (通常、型のメンバーが条件付きで定義されているのに、その型を使用するすべての CPP ファイルの条件が同じでない場合に発生します)。このような場合、リンカーのエラーが発生し、シンボル名と、型が定義されている 2 番目の OBJ ファイルの名前だけが報告されます。(This is usually caused when members of a type are conditionally defined, but the conditions are not the same for all CPP files that use the type.) In this case the linker fails, reporting only the symbol name and the name of the second OBJ file where the type was defined. 多くの場合、OBJ ファイルがリンカーに送られる順序を変更し、他のデータ型バージョンの位置がリンカーにわかるようにすると対処できます。It is often useful to rotate the order that OBJ files are sent to the linker to discover the location of the other version of the data type.

ローダー ロックのデッドロックLoader Lock Deadlock

「ローダー ロックのデッドロック」が発生する可能性しますが、決定的しが検出され、実行時に報告されます。The "loader lock deadlock" can occur, but is deterministic and is detected and reported at runtime. 参照してください混在アセンブリの初期化に関する背景、ガイダンス、およびソリューションの。See Initialization of Mixed Assemblies for detailed background, guidance, and solutions.

データのエクスポートData Exports

DLL データのエクスポートはエラーの原因にもなりやすいため、お勧めしません。Exporting DLL data is error-prone, and not recommended. これは、DLL のデータ セクションは、DLL のマネージド部分の一部が実行されるまで初期化されていると保証されないためです。This is because the data section of a DLL is not guaranteed to be initialized until some managed portion of the DLL has been executed. 参照メタデータを#using ディレクティブします。Reference metadata with #using Directive.

型の可視性Type Visibility

ネイティブ型は、既定ではプライベートです。Native types are private by default. これで、ネイティブ型は DLL の外側では見えなくなります。This can result in a native type not being visible outside the DLL. このエラーを解決するには、これらの型に public を追加します。Resolve this error by adding public to these types.

浮動小数点とアラインメントの問題Floating Point and Alignment Issues

__controlfp 共通言語ランタイムでサポートされていません (を参照してください_control87、_controlfp、 __control87_2詳細については)。__controlfp is not supported on the common language runtime (see _control87, _controlfp, __control87_2 for more information). CLR は反映されませんもalignします。The CLR will also not respect align.

COM の初期化COM Initialization

共通言語ランタイムは、モジュールが初期化されると自動的に COM を初期化します (自動的に初期化される場合、COM は MTA として初期化されます)。The Common Language Runtime initializes COM automatically when a module is initialized (when COM is initialized automatically it’s done so as MTA). その結果、明示的に COM を初期化すると、COM が既に初期化されていることを示すリターン コードが生成されます。As a result, explicitly initializing COM yields return codes indicating that COM is already initialized. COM が CLR によって既にいずれかのスレッド モデルに初期化されている場合、別のスレッド モデルを使用して明示的に COM を初期化しようとすると、アプリケーションが失敗するおそれがあります。Attempting to explicitly initialize COM with one threading model when the CLR has already initialized COM to another threading model can cause your application to fail.

共通言語ランタイムは、既定では MTA として COM を開始します。使用して、 /CLRTHREADATTRIBUTE (CLR スレッド属性の設定)これを変更します。The common language runtime starts COM as MTA by default; use /CLRTHREADATTRIBUTE (Set CLR Thread Attribute) to modify this.

パフォーマンスの問題Performance Issues

MSIL に対して生成されたネイティブの C++ メソッドが (仮想関数呼び出し、または関数ポインターの使用によって) 間接的に呼び出されると、パフォーマンスが低下することがあります。You may see decreased performance when native C++ methods generated to MSIL are called indirectly (virtual function calls or using function pointers). これに関する詳細についてを参照してください。ダブル サンキングします。To learn more about this, see Double Thunking.

ネイティブから MSIL に移動すると、ワーキング セットのサイズが増加することがわかります。When moving from native to MSIL, you will notice an increase in the size of your working set. これは、共通言語ランタイムが、プログラムを正しく実行するための多くの機能を提供するためです。This is because the common language runtime provides many features to ensure that programs run correctly. 場合、 /clrアプリケーションが正しく実行されていない、C4793 を有効にすることがあります (既定でオフ) を参照してくださいコンパイラの警告 (レベル 1 および 3) C4793詳細についてはします。If your /clr application is not running correctly, you may want to enable C4793 (off by default), see Compiler Warning (level 1 and 3) C4793 for more information.

シャットダウン時のプログラムの衝突Program Crashes on Shutdown

場合によっては、マネージド コードが実行を終了する前に CLR がシャットダウンすることがあります。In some cases, the CLR can shutdown before your managed code is finished running. std::set_terminateSIGTERM を使用すると、この問題が発生します。Using std::set_terminate and SIGTERM can cause this. 参照してくださいsignal 定数set_terminate詳細についてはします。See signal Constants and set_terminate for more information.

Visual C++ の新機能の使用Using New Visual C++ Features

アプリケーションのコンパイル、リンク、および実行をした後でコンパイルされたモジュールで .NET 機能の使用を開始できます /clrします。After your application compiles, links, and runs, you can begin using .NET features in any module compiled with /clr. 詳細については、「Component Extensions for Runtime Platforms」を参照してください。For more information, see Component Extensions for Runtime Platforms.

C++ のマネージド拡張を使用していた場合は、新しい構文を使用してコードを変換できます。If you used Managed Extensions for C++, you can convert your code to use the new syntax. C++ マネージ拡張を変換する方法の詳細については、次を参照してください。 C +/cli 移行ガイドします。For details on converting Managed Extensions for C++, see C++/CLI Migration Primer.

Visual C++ での .NET プログラミングの詳細については、以下の項目を参照してください。For information on .NET programming in Visual C++ see:

関連項目See also

混在 (ネイティブおよびマネージド) アセンブリMixed (Native and Managed) Assemblies