Windows ランタイム コンポーネントに配列を渡すPassing arrays to a Windows Runtime Component

Windows ユニバーサル プラットフォーム (UWP) では、パラメーターは入力または出力のどちらかに使用され、両方に使用されることはありません。In the Windows Universal Platform (UWP), parameters are either for input or for output, never both. つまり、メソッドに渡される配列の内容および配列自体は、入力か出力のどちらかに使用されます。This means that the contents of an array that is passed to a method, as well as the array itself, are either for input or for output. 配列の内容が入力に使用される場合、メソッドは配列から読み取りを行いますが、書き込みはしません。If the contents of the array are for input, the method reads from the array but doesn't write to it. 配列の内容が出力に使用される場合、メソッドは配列に書き込みを行いますが、読み取りはしません。If the contents of the array are for output, the method writes to the array but doesn't read from it. .NET の配列は参照型であり、配列の参照が値によって渡された場合でも配列の内容が変更可能であるため、配列パラメーターには問題があります (Visual Basic ではByVal )。This presents a problem for array parameters, because arrays in .NET are reference types, and the contents of an array are mutable even when the array reference is passed by value (ByVal in Visual Basic). Windows ランタイム メタデータのエクスポート ツール (Winmdexp.exe) では、コンテキストから判別できない場合、パラメーターに ReadOnlyArrayAttribute 属性または WriteOnlyArrayAttribute 属性を適用して、配列の用途を指定する必要があります。The Windows Runtime Metadata Export Tool (Winmdexp.exe) requires you to specify the intended usage of the array if it is not clear from context, by applying the ReadOnlyArrayAttribute attribute or the WriteOnlyArrayAttribute attribute to the parameter. 配列の使用方法は、次のように決定されます。Array usage is determined as follows:

  • 戻り値、または出力パラメーター (Visual Basic では、OutAttribute 属性の ByRef パラメーター) の場合、配列は常に出力に使用されます。For the return value or for an out parameter (a ByRef parameter with the OutAttribute attribute in Visual Basic) the array is always for output only. ReadOnlyArrayAttribute 属性は適用しないでください。Do not apply the ReadOnlyArrayAttribute attribute. 出力パラメーターで WriteOnlyArrayAttribute 属性を適用することはできますが、冗長になります。The WriteOnlyArrayAttribute attribute is allowed on output parameters, but it's redundant.

    注意   Visual Basic コンパイラでは、出力のみの規則は適用されません。Caution  The Visual Basic compiler does not enforce output-only rules. 出力パラメーターからの読み取りは行わないでください。Nothing が含まれている可能性があります。You should never read from an output parameter; it may contain Nothing. 常に新しい配列を割り当ててください。Always assign a new array.  

  • ref 修飾子 (Visual Basic では ByRef) を持つパラメーターは使用できません。Parameters that have the ref modifier (ByRef in Visual Basic) are not allowed. Winmdexp.exe によりエラーが生成されます。Winmdexp.exe generates an error.

  • 値で渡されるパラメーターの場合、ReadOnlyArrayAttribute 属性または WriteOnlyArrayAttribute 属性を適用して、配列の内容が入力と出力のどちらで使用されるのかを指定する必要があります。For a parameter that is passed by value, you must specify whether the array contents are for input or output by applying either the ReadOnlyArrayAttribute attribute or the WriteOnlyArrayAttribute attribute. 両方の属性を指定すると、エラーになります。Specifying both attributes is an error.

メソッドで、入力の配列を受け取り、配列の内容を変更して、呼び出し元に配列を返す必要がある場合、入力には読み取り専用のパラメーター、出力には書き込み専用のパラメーター (または戻り値) を使用します。If a method must accept an array for input, modify the array contents, and return the array to the caller, use a read-only parameter for the input and a write-only parameter (or the return value) for the output. 次のコードは、このパターンを実装する 1 つの方法を示します。The following code shows one way to implement this pattern:

public int[] ChangeArray([ReadOnlyArray()] int[] input)
{
    int[] output = input.Clone();
    // Manipulate the copy.
    //   ...
    return output;
}
Public Function ChangeArray(<ReadOnlyArray> input() As Integer) As Integer()
    Dim output() As Integer = input.Clone()
    ' Manipulate the copy.
    '   ...
    Return output
End Function

すぐに入力の配列をコピーして、利用することをお勧めします。We recommend that you make a copy of the input array immediately, and manipulate the copy. これにより、コンポーネントが .NET コードによって呼び出されたかどうかにかかわらず、メソッドの動作が同じになります。This helps ensure that the method behaves the same whether or not your component is called by .NET code.

マネージ コードおよびアンマネージ コードからコンポーネントを使用するUsing components from managed and unmanaged code

ReadOnlyArrayAttribute 属性または WriteOnlyArrayAttribute 属性を持つパラメーターは、呼び出し元がネイティブ コードで記述されているか、マネージ コードで記述されているかによって、動作が異なります。Parameters that have the ReadOnlyArrayAttribute attribute or the WriteOnlyArrayAttribute attribute behave differently depending on whether the caller is written in native code or managed code. 呼び出し元が、ネイティブ コード (JavaScript、または Visual C++ コンポーネント拡張機能) の場合、配列の内容は次のように処理されます。If the caller is native code (JavaScript or Visual C++ component extensions), the array contents are treated as follows:

  • ReadOnlyArrayAttribute: アプリケーション バイナリ インターフェイス (ABI) の境界を越えた呼び出しの場合、配列はコピーされます。ReadOnlyArrayAttribute: The array is copied when the call crosses the application binary interface (ABI) boundary. 要素は必要に応じて変換されます。Elements are converted if necessary. そのため、誤ってメソッドによって入力専用配列に変更が加えられたとしても、呼び出し元からは見えません。Therefore, any accidental changes the method makes to an input-only array are not visible to the caller.
  • WriteOnlyArrayAttribute: 呼び出されたメソッドでは、元の配列の内容を推測できません。WriteOnlyArrayAttribute: The called method can't make any assumptions about the contents of the original array. たとえば、メソッドが受け取る配列が初期化されていなかったり、既定の値が入っていたりする可能性があります。For example, the array the method receives might not be initialized, or might contain default values. メソッドには、配列内のすべての要素の値を設定することが期待されます。The method is expected to set the values of all the elements in the array.

呼び出し元がマネージコードの場合は、.NET のメソッド呼び出しの場合と同様に、呼び出されたメソッドで元の配列を使用できます。If the caller is managed code, the original array is available to the called method, as it would be in any method call in .NET. 配列の内容は .NET コードで変更可能であるため、メソッドが配列に対して行う変更は呼び出し元から参照できます。Array contents are mutable in .NET code, so any changes the method makes to the array are visible to the caller. これは、Windows ランタイム コンポーネント用に作成された単体テストに影響するため、注意してください。This is important to remember because it affects unit tests written for a Windows Runtime Component. マネージド コードでテストが作成される場合、配列の内容はテスト中に変更可能であることが示されます。If the tests are written in managed code, the contents of an array will appear to be mutable during testing.