COM API - не удалось передать «NULL» для аргумента указателя - PullRequest
0 голосов
/ 16 апреля 2009

У меня есть COM API foo, IDL выглядит так:

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

когда я использую эту функцию с foo(0,NULL); Я получаю ошибку - аргумент NULL передан. Есть ли способ обойти это?

Ответы [ 5 ]

2 голосов
/ 16 апреля 2009

Вы пытались передать пустую строку?

unsigned char Data = 0;
foo(0,&Data);
0 голосов
/ 18 апреля 2009

foo возможно реализовано так:

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

В этом случае единственный обходной путь - передать ненулевые pData.

0 голосов
/ 18 апреля 2009

Если вы передаете BSTR, вам просто нужно передать значение BSTR - они уже подсчитаны по длине (используйте SysStrLength, чтобы найти длину).

Если вы хотите передать строку с нулевым символом в конце, используйте атрибут [string], как сказал Грег

Но ответ на ваш реальный вопрос заключается в том, что вам нужно пометить строковый параметр как «уникальный» - что позволяет компилятору MIDL (и библиотеке времени выполнения RPC) знать, что для этого параметра допустимо NULL.

Так что используйте:

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

Вам не нужно поле длины, потому что это строка с нулевым окончанием - поэтому вы можете использовать strlen в строке.

0 голосов
/ 16 апреля 2009

Не используйте char * в COM API - используйте вместо этого BSTR. Затем передайте пустую строку.

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

...

foo(1, _bstr_t(""));
0 голосов
/ 16 апреля 2009

Вы, вероятно, должны пометить символ * как строку, чтобы получить некоторую помощь с маршалингом.

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

Мы не используем опцию size_is в IDL, возможно, она вызывает проблему с ненулевым адресом?

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

Я бы определенно рекомендовал использовать BSTR или SAFEARRAY, а не char. Тогда проблема будет в том, как лучше всего обработать этот пустой случай, возможно, обработав его так же, как пустую строку, или используя отдельный метод.

Передача указателей в COM очень плохая форма, например, передача указателя с использованием разделяемой памяти (потенциально / вероятный) удаленный процесс не будет иметь доступа к памяти. Таким образом, COM пытается помочь, используя для вас фактические данные, но если вы спрятали их за другим типом данных, они не будут правильно обрабатывать данные. Например, используя wchar_t *, он создаст выделенную системой строку, доступную между процессами. или вы можете сделать то же самое и получить интерфейс, принимающий bstring и передавающий ему результат sysallocstring ()

Возможно, вы могли бы рассказать нам больше о структуре, которую вы хотите использовать, возможно, было бы более целесообразно расширить интерфейс com объектами этого типа. Или может быть какая-то другая хитрость в мартиаллинге для передачи данных, вы можете написать собственные методы мартиллинга для сериализации и десериализации контента.

...