COM API - 无法为指针参数传递“NULL”

时间:2009-04-16 08:04:35

标签: c++ winapi com midl

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

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

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

5 个答案:

答案 0 :(得分:2)

你试过传递一个空字符串吗?

unsigned char Data = 0;
foo(0,&Data);

答案 1 :(得分: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接口可能更合适。或者在martialling中可能还有其他一些技巧来传输数据,你可以编写自定义的martialling方法来序列化和反序列化内容。

答案 2 :(得分:0)

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

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

...

foo(1, _bstr_t(""));

答案 3 :(得分:0)

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

如果要传入空终止字符串,请使用[string]属性,如Greg所说

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

所以使用:

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

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

答案 4 :(得分:0)

foo可能是这样实现的:

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

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