COM API foo があります。IDL は次のようになります。
foo([in] unsigned long ulSize, [in, size_is(ulSize)] unsigned char* pData)
この関数を使用するとfoo(0,NULL);
エラーが発生します - NULL 引数が渡されました。これを回避する方法はありますか?
空の文字列を渡してみましたか?
unsigned char Data = 0;
foo(0,&Data);
BSTRを渡す場合は、BSTR値を渡す必要があります-それらはすでに長さをカウントされています(長さを見つけるにはSysStrLengthを使用してください)。
nullで終了する文字列を渡す場合は、Gregが言ったように[string]属性を使用します
しかし、実際の質問に対する答えは、文字列パラメーターを「一意」としてマークする必要があるということです。これにより、MIDLコンパイラー(およびRPCランタイムライブラリ)は、そのパラメーターがNULLであっても問題ないことを認識できます。
したがって、以下を使用します。
foo([in, string] unsigned char* pData)
長さフィールドはnullで終了する文字列であるため、必要ありません。そのためstrlen
、文字列で使用できます。
マーシャリングを支援するために、おそらく char* を as string としてマークする必要があります。
foo([in] unsigned long ulSize, [in,string,size_is(ulSize)] unsigned char* pData)
IDL では size_is オプションを使用しません。おそらく、NULL 以外のアドレスを持つという問題が発生するのでしょうか?
foo([in] unsigned long ulSize, [in,string] unsigned char* pData)
char ではなく BSTR または SAFEARRAY を使用することをお勧めします。問題は、この空のケースをどのように処理するのが最善か、おそらく同じものを空の文字列として扱うか、別のメソッドを持つことです。
COM でポインターを渡すことは非常に悪い形式です。たとえば、共有メモリを使用してポインターを渡すと、(潜在的/可能性が高い) リモート プロセスがメモリにアクセスできなくなります。そのため、COM は実際のデータをマーチャリングして支援しようとしますが、別のデータ型の背後に隠していると、データを適切にマーチャリングできません。たとえば、wchar_t* を使用すると、プロセス間で使用可能なシステム割り当て文字列が作成されます。または、同じことを行って、bstring を取得するインターフェイスを作成し、sysallocstring() の結果を渡すことができます。
使用したい構造について詳しく教えていただければ、このタイプのオブジェクトで com インターフェイスを拡張する方が適切かもしれません。または、データを転送するマーチャリングに他のトリックがある可能性があります。コンテンツをシリアライズおよびデシリアライズするカスタム マーチャリング メソッドを作成できます。
COM API では char* を使用しないでください。代わりに BSTR を使用してください。次に空の文字列を渡します。
foo([in] unsigned long ulSize, [in] BSTR pData)
...
foo(1, _bstr_t(""));
foo
おそらく次のように実装されています。
HRESULT foo(unsigned long ulSize, unsigned char* pData) {
if (!pData) {
return E_POINTER;
}
...
}
この場合の唯一の回避策は、NULL 以外の pData を渡すことです。