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

发布于 2024-07-16 13:49:21 字数 206 浏览 10 评论 0原文

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

快乐很简单 2024-07-23 13:49:21

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

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

Have you tried passing an empty string?

unsigned char Data = 0;
foo(0,&Data);
金橙橙 2024-07-23 13:49:21

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

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

...

foo(1, _bstr_t(""));

Don't use char* in COM APIs -- use BSTR instead. Then pass an empty string.

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

...

foo(1, _bstr_t(""));
流年里的时光 2024-07-23 13:49:21

您可能应该将 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 接口可能更合适这个类型。 或者,武术中可能有其他一些技巧来传输数据,您可以编写自定义武术方法来序列化和反序列化内容。

You should probably mark the char* as as string to get some assistance with the marshaling.

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

We don't use the size_is option in the IDL, perhaps it is forcing the issue of having a non NULL address?

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

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.

喜爱皱眉﹌ 2024-07-23 13:49:21

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

如果你想传递一个以 null 结尾的字符串,请使用 [string] 属性,正如 Greg 所说,

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

因此使用:

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

您不需要长度字段,因为它是一个以 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:

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

You don't need the length field because it's a null terminated string - so you can use strlen on the string.

夜深人未静 2024-07-23 13:49:21

foo 可能是这样实现的:

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

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

foo is probably implemented like this:

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

In this case the only workaround is to pass non-NULL pData.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文