次のインターフェイスとクラス宣言を備えた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#メソッドは渡されたメモリ(ピン留めされる可能性があります)を直接操作しますか?