0

我有一个 COM API foo,IDL 看起来像:

foo([in] unsigned long ulSize, [in, size_is(ulSize)] unsigned char* pData)

当我使用这个函数时,foo(0,NULL); 我得到一个错误 - NULL 参数传递。有没有办法解决这个问题?

4

5 回答 5

2

您是否尝试过传递一个空字符串?

unsigned char Data = 0;
foo(0,&Data);
于 2009-04-16T08:21:10.593 回答
0

您可能应该将 char* 标记为字符串以获得一些编组帮助。

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)

我当然会推荐使用 BSTR 或 SAFEARRAY 而不是 char。那么问题将是如何最好地处理这种空情况,可能将其视为空字符串,或者有一个单独的方法。

在 COM 中传递指针是非常糟糕的形式,就像使用共享内存传递指针一样,(可能/可能)远程进程将无法访问内存。因此,COM 试图通过为您军事化实际数据来提供帮助,但如果您将其隐藏在不同的数据类型后面,它就不会正确地军事化数据。例如,使用 wchar_t* 它将创建一个在进程之间可用的系统分配字符串。或者你可以做同样的事情并有一个接口接受一个 bstring 并将 sysallocstring() 的结果传递给它

或许你可以告诉我们更多关于你想要使用的结构,用这种类型的对象扩展com接口可能更合适。或者可能有一些其他的技巧来传输数据,您可以编写自定义的军事方法来序列化和反序列化内容。

于 2009-04-16T08:45:37.383 回答
0

不要在 COM API 中使用 char* —— 改用 BSTR。然后传递一个空字符串。

foo([in] unsigned long ulSize, [in] BSTR pData)

...

foo(1, _bstr_t(""));
于 2009-04-16T12:45:55.443 回答
0

如果您要传递 BSTR,您应该只传递 BSTR 值 - 它们已经计算了长度(使用 SysStrLength 来查找长度)。

如果您想传入一个以空字符结尾的字符串,请使用 Greg 所说的 [string] 属性

但是您的实际问题的答案是您需要将字符串参数标记为“唯一” - 这让 MIDL 编译器(和 RPC 运行时库)知道该参数可以为 NULL。

所以使用:

foo([in, string] unsigned char* pData)

您不需要长度字段,因为它是一个以空值结尾的字符串 - 因此您可以strlen在字符串上使用。

于 2009-04-18T14:50:51.123 回答
0

foo可能是这样实现的:

HRESULT foo(unsigned long ulSize, unsigned char* pData) {
  if (!pData) {
    return E_POINTER;
  }
  ...
}

在这种情况下,唯一的解决方法是传递非 NULL pData。

于 2009-04-18T15:15:16.883 回答