COM API - 无法传递“NULL” 对于指针参数
我有一个 COM API foo,IDL 如下所示:
foo([in] unsigned long ulSize, [in, size_is(ulSize)] unsigned char* pData)
当我使用 foo(0,NULL); 使用此函数时 我收到错误 - 传递了 NULL 参数。 有办法解决这个问题吗?
I have a COM API foo, the IDL looks like:
foo([in] unsigned long ulSize, [in, size_is(ulSize)] unsigned char* pData)
when I consume this function with foo(0,NULL);
I get an error - NULL argument passed. Is there a way to workaround this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您是否尝试过传递空字符串?
Have you tried passing an empty string?
不要在 COM API 中使用 char*——而是使用 BSTR。 然后传递一个空字符串。
Don't use char* in COM APIs -- use BSTR instead. Then pass an empty string.
您可能应该将 char* 标记为字符串以获得编组方面的帮助。
我们在 IDL 中没有使用 size_is 选项,也许它强制解决了非 NULL 地址的问题?
我当然建议使用 BSTR 或 SAFEARRAY 而不是 char。 那么问题将是如何最好地处理这种空情况,可能将其视为空字符串,或者使用单独的方法。
在 COM 中传递指针是非常糟糕的形式,就像使用共享内存传递指针一样,(可能/可能)远程进程将无法访问该内存。 因此,COM 试图通过为您管理实际数据来提供帮助,但如果您将其隐藏在不同的数据类型后面,它将无法正确地管理数据。 例如,使用 wchar_t* 它将创建一个在进程之间可用的系统分配字符串。 或者你可以做同样的事情,让一个接口接受 bstring 并将其传递给 sysallocstring() 的结果。
也许你可以告诉我们更多关于你想要使用的结构的信息,用以下对象扩展 com 接口可能更合适这个类型。 或者,武术中可能有其他一些技巧来传输数据,您可以编写自定义武术方法来序列化和反序列化内容。
You should probably mark the char* as as string to get some assistance with the marshaling.
We don't use the size_is option in the IDL, perhaps it is forcing the issue of having a non NULL address?
I'd certainly recommend using BSTR or SAFEARRAY rather than char. The issue would then be how to handle this empty case best, possibly treating the same as an empty string, or having a separate method.
Passing pointers in COM is very bad form, like passing a pointer using shared memory the (potentially/likely) remote process will not have access to the memory. As such COM tries to help by martialling the actual data for you, but if you have hidden it behind a different data type it won't be martialling the data properly. For instance using wchar_t* it will create a system allocated string available between the processes. or you can do the same and have an interface taking a bstring and pass it the result of a sysallocstring()
Perhaps you could tell us more about the structure you want to use, it might be more appropriate to expand the com interface with objects of this type. Or there may be some other trick in martialling to transfer the data, you can write custom martialling methods to serialize and deserialize the content.
如果您要传递 BSTR,则应该只传递 BSTR 值 - 它们已经计算了长度(使用 SysStrLength 来查找长度)。
如果你想传递一个以 null 结尾的字符串,请使用 [string] 属性,正如 Greg 所说,
但你实际问题的答案是,你需要将字符串参数标记为“唯一” - 这让 MIDL 编译器(和 RPC运行时库)知道该参数可以为 NULL。
因此使用:
您不需要长度字段,因为它是一个以 null 结尾的字符串 - 因此您可以在字符串上使用
strlen
。If you're passing in a BSTR you should just pass the BSTR value - they're already length counted (use SysStrLength to find the length).
If you want to pass in a null terminated string, use the [string] attribute as Greg said
But the answer to your actual question is that you need to mark the string parameter as "unique" - that lets the MIDL compiler (and the RPC runtime library) know that it's ok for that parameter to be NULL.
So use:
You don't need the length field because it's a null terminated string - so you can use
strlen
on the string.foo
可能是这样实现的:在这种情况下,唯一的解决方法是传递非 NULL pData。
foo
is probably implemented like this:In this case the only workaround is to pass non-NULL pData.