6

out对于 C++ COM dll 中的接口,我有一个BSTR* 值。我将此返回给 C# .Net 客户端。在我的 C++ 函数中,我必须根据差异条件分配不同的值。

例如:

If my function is fun(BSTR* outval)
{
   // I have to assign a default value to it such as:
   *outval = SysAllocSTring(L"N");

   Then I will check for some DB conditions
   { 
     // And I have to allocate it according to that.
     // Do I need to again calling SysAllocString?
     eq.*outval = SySAllocString(DBVlaue);
   }
}

如果我两次调用 SysAllocSTring 到同一个 BSTR 会发生什么?处理这个问题的最佳方法是什么?

4

4 回答 4

9

BSTR除了您实际作为“out”参数传递的那个之外,您必须处理所有的 s。你传递出去的BSTR东西不需要被释放——调用者负责释放它,你的代码负责BSTR它可能分配的所有其他 s。

如果你真的需要那些临时BSTRs,你应该使用一个包装类,比如ATL::CComBSTR_bstr_t用于那些临时BSTRs(但不是你传递的那个)。我想在您描述的情况下,您最好只重写您的代码,这样您就不需要BSTR在任何控制路径上进行更多的创建。

这是一些伪代码:

 HRESULT YourFunction( BSTR* result )
 {
     if( result == 0 ) {
         return E_POINTER;
     }
     int internalStateValue = getState();
     if( internalStateValue > 0 ) { // first case
         *result = SysAllocString( "positive" );
     } else if( internalStateValue < 0 ) { //second case
         *result = SysAllocString( "negative" );
     } else { //default case
         *result = SysAllocString( "zero" );
     }
     return S_OK;
  }
于 2011-05-27T08:28:02.370 回答
3

除了 Martyn 回答的内容之外,您应该尝试为此使用CComBSTR,它会自动处理分配和释放 BSTR。

顺便说一句,CComBSTR 类是RAII的一个示例

于 2011-05-27T05:46:03.630 回答
2

如果您调用 SysAllocString 两次,您将泄漏第一个 BSTR。你不应该这样做。您可以改为在第一个 BSTR 上使用 SysFreeString,然后在第二个上使用 SysAllocString,或者更简单地调用 SysReAllocString 来重新分配现有的 BSTR 值。

马丁

于 2011-05-27T05:25:42.977 回答
0

如果您的功能定义为:

HRESULT Foo(BSTR input){...}

像这样称呼它:

Foo(_bstr_t(L"abc"));
于 2013-07-24T17:36:07.123 回答