Я хочу написать DCOM-сервер и клиент, чтобы они могли обмениваться некоторыми данными. Обе стороны скомпилированы с использованием MS Visual Studio 2008, клиент подключается с использованием чистого WinAPI, proxy/stub - отдельная dll (в случае, если что-либо из этого имеет значение). Проблема в том, что я не могу вернуть массив строк (он заполнен правильно, но клиент получает массив пустых строк).SAFEARRAY (BSTR) как параметр [out] в DCOM не возвращает строки
Сервер: IDL декларации COM интерфейса имеет этот метод:
[id(7)] HRESULT foo([in] int arg1, [out] SAFEARRAY(int)* arg2, [out] SAFEARRAY(BSTR)* arg3);
осуществление, с заголовком, сгенерированные студиями:
HRESULT STDMETHODCALLTYPE CoClass::foo(int arg1, SAFEARRAY** arg2, SAFEARRAY** arg3){
SAFEARRAYBOUND bounds;
bounds.cElements = arg1;
bounds.lBound = 0;
*arg2 = SafeArrayCreate(VT_INT, 1, &bounds);
*arg3 = SafeArrayCreate(VT_BSTR, 1, &bounds);
for(LONG i=0; i<arg1; ++i){
int int_value = 42;
BSTR string_value = SysAllocString(L"Hello");
//string_value is correct here
SafeArrayPutElement(*arg2, &i, &int_value);
SafeArrayPutElement(*arg3, &i, &string_value);
//string_value isn't destroyed here (explicitly, at least)
}
return ERROR_SUCCESS;
}
Клиент: Включенной Студией сгенерированного заголовка:
virtual /* [id] */ HRESULT STDMETHODCALLTYPE foo(
/* [in] */ int arg1,
/* [out] */ SAFEARRAY * *arg2,
/* [out] */ SAFEARRAY * *arg3) = 0;
код вызывающего абонента (pInterface
правильно инициализирован, другие вызовы успешны):
SAFEARRAY *pInts = NULL, *pStrings = NULL;
HRESULT error = pInterface->foo(23, &pInts, &pStrings);
// in debugger:
// error is ERROR_SUCCESS, pInts filled properly,
// pStrings is an array of 23 NULLs
Другие детали:
- Там нет другого метода с ID 7 в IDL-файла;
- Использование
[out] BSTR *str
работает, строка возвращается правильно; pInterface
получен изCoCreateInstanceEx
звонок;- В системе нет старой версии сервера;
- Код должен быть запущен в Windows XP без каких-либо обновлений, поэтому использование Visual Studio 2008 - это ограничение, которое трудно обойти.
Есть ли у кого-нибудь идеи, что я делаю неправильно?
BSTR уже указатель, проход string_value вместо & string_value. –
@ HansPassant ... это сработало. Спасибо. Вы хотите написать ответ, или я должен сделать это сам? – Abstraction
Я уверен, что теперь вы знаете, как написать правильный ответ, пойти на это. –