我有一个带有以下方法定义(IDL 表示法)的 COM 接口:

SCODE GetText( [in, out] ULONG* pcwcBuffer,
              [out, size_is(*pcwcBuffer)] WCHAR* awcBuffer );

Typelib 封送处理用于 COM+,类型库已注册,通过 COM+ 调用时接口的其他方法可以正常工作,但此方法不行。

服务器端将 WCHAR 数组复制到 awcBuffer 及其长度为 pwcBuffer, ,不会发生缓冲区溢出。

static const wchar_t* Text = L"Sample";
STDMETHODIMP CImpl::GetText( ULONG* bufferLength, WCHAR* buffer )
{
    const int length = wcslen( Text );
    *bufferLength = length;
    memcpy( buffer, Text, length * sizeof( WCHAR ) );
    return S_OK;
}

当客户端通过 COM+ 调用此方法时,缓冲区内容将丢失。具体来说,仅保留第一个宽字符 - 如果服务器复制“Sample”宽字符串,则客户端仅接收“S”字符串。客户端大小的返回值为S_OK,返回给客户端的缓冲区长度与服务器复制的完全相同。

我最终改用 BSTR 来解决这个问题,但真正有趣的是为什么整个看起来有效的构造不起作用。

所描述的行为的可能原因是什么?

有帮助吗?

解决方案

IIRC,类型库编组忽略size_is属性 - 因此,只有1炭封

其他提示

学家传球是正确的。对于类型库编组工作,COM接口必须是OLE自动化兼容。该类型库编组中的oleaut32.dll实现的,所以我想有在名称中的线索。

[size_is]是完全有效的IDL,并且编译成一个有效的类型库,但类型库封送只能处理的有效接口的子集。该子集通常被称为OLE自动化。顺便说一句,VB6客户端只能说OLE自动化,所以他们将无法要么消耗你的界面。

尝试使用在IDL的[了oleautomation]属性标记的接口。它应该给你,可能指向你关于这个问题的更多信息,警告或错误信息。

在“正常”的COM,你可以生成从IDL代理/存根DLL做编组,但是我怕我不记得COM +是否会使用自定义编组代码,即使你不屑于建立它

更新:在朱瓦尔·洛书“COM和.NET组件服务”,我发现这样的说法:“ ...配置的组件不能使用需要自定义编组的接口”。所以我想这个接口将永远不会在COM +工作。如果可以的话,重新编写使用BSTR来代替。

有几个问题:

  • 你为什么不使用 BSTR?
  • 你有资源吗 GetText 功能?
  • 函数返回的缓冲区大小是多少?
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top