0

次のインターフェイスとクラス宣言を備えたC#/。Net COMサーバー(COM-visibleアセンブリ)があります。

[ComVisible(true)]
[Guid( "..." )]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITest
{
    void TestMethod( [In] int nNumElements, 
                     [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] byte [] bArray );
}

[ComVisible(true)]
[Guid( "..." )]
[ClassInterface( ClassInterfaceType.None )]
[ProgId( "CSCOMServer.CSTest" )]
public class CSTest : ITest
{
    public void TestMethod( int nNumElements, byte [] bArray )
    {
        for (int i = 0; i < bArray.Length; i++)
        {
            bArray [i] = (byte)i;
        }
    }
}

結果のIDL/typelibは次のとおりです。

...
interface ITest : IUnknown {
    HRESULT _stdcall TestMethod(
                    [in] long nNumElements, 
                    [in, out] unsigned char* bArray);
};

...
coclass CSTest {
    interface _Object;
    [default] interface ITest;
};

目標は、C ++ COMクライアントからこれを利用できるようにすることです。これは、以下を使用して正常に機能します。

int iSize = 10;
ITest *test;
byte *buf  = (byte*)CoTaskMemAlloc( iSize * sizeof(byte) );
CoCreateInstance( CLSID_CSTest, NULL, CLSCTX_INPROC_SERVER, IID_ITest, (void **) &test );
test->TestMethod( iSize, buf );

バッファーはC++によって割り当てられ、ポピュレーションのためにC#に渡されます。すべてが正常に機能し、TestMethod()が完了すると、C ++配列(buf)にはC#メソッドによって設定された正しい値が含まれます。

問題は効率についてです
。相互運用機能ラッパーは、マーシャリング中に配列コピーを実行し(「In」フェーズ)、次に戻る(「Out」フェーズ)か、またはC#メソッドは渡されたメモリ(ピン留めされる可能性があります)を直接操作しますか?

4

2 に答える 2

2

いいえ、構造の変更を要求するため、ここでは必ずコピーが必要です。CLRは、byte[]引数タイプの要件を満たすためにマネージ配列オブジェクトを作成する必要があります。また、ソース配列はメモリの生のチャンクにすぎないため、そのままでは使用できません。逆の方法(byte[]からunsignedchar *)でも機能しますが、ここではそうではありません。

アレイの通常のCOM自動化タイプはSAFEARRAYですが、速度の利点はありませんが、サーバーを使用できるCOMクライアントは他にもたくさんあります。

于 2012-07-10T17:07:01.723 に答える
1

この場合、参照はアンマネージコードとマネージコードの間で渡されます。「ピン留めの最適化」は、in / outパラメーターが指定されていない場合でも、特定の場合にそれを行います(ただし、tlibとして使用するには、常にin / out修飾子を指定する必要があります)。

プリミティブ型の単一次元配列は、同じアパートメントで実行されているアンマネージコードとマネージコードの間に常に固定(参照によって渡される)されると想定できます。

詳細については、http: //msdn.microsoft.com/en-us/library/z6cfh6e6 (v = vs.80).aspxを参照してください。

「ピン留めの最適化」の詳細:http: //msdn.microsoft.com/en-us/library/23acw07k.aspx

于 2012-07-10T14:58:04.807 に答える