Ошибка «SafeArray не может быть преобразована в этот тип массива» - PullRequest
0 голосов
/ 28 марта 2019

У меня есть локальный сервер C ++ COM и клиент C #. Код сервера:

// MyStruct as define in the _i.h file
typedef /* [uuid] */  DECLSPEC_UUID("...") struct MyStruct
{
SAFEARRAY * FormatData;
LONG aLong;
BOOL aBool;
}   MyStruct;

// Server method being invoked
STDMETHODIMP CMyClass::Foo(MyStruct* StreamInfo, int* result)
{
  long Length;
  BYTE* Data;
  GetData(Length, Data);
  PackBytes(Length, Data, &(StreamInfo->FormatData));
}

PackBytes преобразует массив BYTE в SAFEARRAY. Это взято из этого вопроса стекопотока . Он устанавливает границу и размерность SAFEARRAY.

Код клиента:

MyStruct myStruct;
int rc = obj.Foo(out myStruct);

Где MyStruct импортируется из сборки COM. это выглядит как

public struct MyStruct
{
  public Array FormatData;
  int aLong;
  int aBool;
}

После запуска Foo появляется ошибка «SafeArray нельзя маршалировать для этого типа массива, поскольку он имеет ненулевые нижние границы или более одного измерения» с дополнительным примечанием «Убедитесь, что у вашего массива есть необходимое количество измерений».

При отладке кода сервера кажется, что Data правильно заполнен в FormatData: как видно на скриншоте ниже. cElements равно Length, а 18 частей данных совпадают с теми, что указаны в Data.

enter image description here

Жесткое кодирование Length = 1 не помогло. Удаление вызова PackByets привело к исчезновению ошибки (другие поля были переданы нормально). Как это можно исправить?

1 Ответ

0 голосов
/ 28 марта 2019

Метод PackBytes, на который вы ссылались, создает SAFEARRAY с нижней границей, равной 1. Построение его с нижней границей, равной нулю, может решить проблему:

SAFEARRAYBOUND bound{ count, 0 };
...