вернуть строку из Invoke (bcb)
От: twask  
Дата: 10.01.02 19:23
Оценка:
мне нужно вернуть строку из функции, которую дергает js-скрипт в webbrowser control.
сейчас делаю так:

HRESULT STDMETHODCALLTYPE TDocHostDispatch::Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
UINT *puArgErr)
{
switch (dispIdMember)
{
case DISPID_getreminderdate:
Idx = (int)Variant(pDispParams->rgvarg[0]);
VariantInit(pVarResult);
V_VT(pVarResult) = VT_BSTR;
V_BSTR(pVarResult) = AnsiToOLESTR((char *)_GetReminderDate(Idx).c_str());
break;
case DISPID_getreminderdescr:
Idx = (int)Variant(pDispParams->rgvarg[0]);
VariantInit(pVarResult);
V_VT(pVarResult) = VT_BSTR;
V_BSTR(pVarResult) = AnsiToOLESTR((char *)_GetReminderDescr(Idx).c_str());
break;
}

return S_OK;
}

_GetReminderDate(Idx) и _GetReminderDescr(Idx) возвращают AnsiString.

если я ограничиваюсь вызовом external.GetReminderDate(1), то все правильно отрабатывает, если я делаю следующим образом:

t = external.GetReminderDescr(1);
s = external.GetReminderDate(1);
alert(s + t);

то в диалоге появляется результат работы только одной функции (почему-то именно GetReminderDate, независимо от порядка вызова). очевидно, что грабли с распределением памяти, но как их обойти я не знаю. что делать?
Re: вернуть строку из Invoke (bcb)
От: Lexey Россия  
Дата: 10.01.02 19:49
Оценка:
Здравствуйте twask, Вы писали:

Думаю, что неправильны у тебя вот эти 2 строчки:

T> V_BSTR(pVarResult) = AnsiToOLESTR((char *)_GetReminderDate(Idx).c_str());


T> V_BSTR(pVarResult) = AnsiToOLESTR((char *)_GetReminderDescr(Idx).c_str());


Ты возвращает указатель на OLESTR, а не BSTR. OLESTR по структуре выглядит также, но память под BSTR распределяется совсем иначе.

T>то в диалоге появляется результат работы только одной функции (почему-то именно GetReminderDate, независимо от порядка вызова). очевидно, что грабли с распределением памяти, но как их обойти я не знаю. что делать?


Замени это дело на:
V_BSTR(pVarResult) = SysAllocString(_GetReminderDate(Idx).c_str()) (ну и вторую соответственно).
Re[2]: вернуть строку из Invoke (bcb)
От: twask  
Дата: 11.01.02 15:28
Оценка:
Здравствуйте Lexey, Вы писали:

T>> V_BSTR(pVarResult) = AnsiToOLESTR((char *)_GetReminderDate(Idx).c_str());


T>> V_BSTR(pVarResult) = AnsiToOLESTR((char *)_GetReminderDescr(Idx).c_str());


L>Ты возвращает указатель на OLESTR, а не BSTR. OLESTR по структуре выглядит также, но память

>под BSTR распределяется совсем иначе.

T>>то в диалоге появляется результат работы только одной функции (почему-то именно

>GetReminderDate, независимо от порядка вызова). очевидно, что грабли с распределением памяти,
>но как их обойти я не знаю. что делать?

L>Замени это дело на:

L>V_BSTR(pVarResult) = SysAllocString(_GetReminderDate(Idx).c_str()) (ну и вторую
>соответственно).

спасибо! это то, что надо.
финальный вариант выглядит следующим образом:
V_BSTR(pVarResult) = SysAllocString(AnsiToOLESTR((char *)_GetReminderDate(Idx).c_str()));


кстати, возможно ли возвращать результат не только в pVarResult, но и в аргументы?
что-то в духе:
procedure x(a, b: integer; var y, z: integer);
begin
y := a + b;
z := a — b;
end;
Re[3]: вернуть строку из Invoke (bcb)
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.01.02 18:31
Оценка:
Здравствуйте twask, Вы писали:

T>кстати, возможно ли возвращать результат не только в pVarResult, но и в аргументы?

T>что-то в духе:
T>procedure x(a, b: integer; var y, z: integer);
T>begin
T> y := a + b;
T> z := a — b;
T>end;

Ну, так передавай их VT_BYREF и все.

PS

Вот только непойму... зачем диспач вручную реализовывать?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: вернуть строку из Invoke (bcb)
От: twask  
Дата: 12.01.02 13:23
Оценка:
Здравствуйте VladD2, Вы писали:

T>>кстати, возможно ли возвращать результат не только в pVarResult, но и в аргументы?

T>>что-то в духе:
T>>procedure x(a, b: integer; var y, z: integer);
T>>begin
T>> y := a + b;
T>> z := a — b;
T>>end;

VD>Ну, так передавай их VT_BYREF и все.


можно пример?

VD>Вот только непойму... зачем диспач вручную реализовывать?


я пока не вижу другого способа реализовать external для webbrowser control.
Re[5]: вернуть строку из Invoke (bcb)
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.01.02 19:42
Оценка:
Здравствуйте twask, Вы писали:

VD>>Ну, так передавай их VT_BYREF и все.


T>можно пример?


Ну, примерно так:

VARIANR var;

var.vt = VT_BYREF | VT_BSTR;
BSTR bstr = NULL;
var.pbstrVal = &bstr;

// далее вызываем Invoke...

// после чего используем значение возвращенное в bstr.


Думаю, как использовать параметр типа VT_BYREF | VT_BSTR понятно и так.

VD>>Вот только непойму... зачем диспач вручную реализовывать?


T>я пока не вижу другого способа реализовать external для webbrowser control.


Что такое "external для" в твоем понимании. А у WebBrowser-а есть нормальный интерфейс (custom-часть). Ее можно и так вызывать. Вообще непонятно причем здесь вообще диспач и передача параметров?...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: вернуть строку из Invoke (bcb)
От: twask  
Дата: 14.01.02 08:56
Оценка:
VD>>>Ну, так передавай их VT_BYREF и все.

T>>можно пример?


VD>Ну, примерно так:


VD>
VD>VARIANR var;

VD>var.vt = VT_BYREF | VT_BSTR;
VD>BSTR bstr = NULL;
VD>var.pbstrVal = &bstr;

VD>// далее вызываем Invoke...

VD>// после чего используем значение возвращенное в bstr.
VD>


VD>Думаю, как использовать параметр типа VT_BYREF | VT_BSTR понятно и так.


только мне вызывать из javascript надо.

VD>>>Вот только непойму... зачем диспач вручную реализовывать?


T>>я пока не вижу другого способа реализовать external для webbrowser control.


VD>Что такое "external для" в твоем понимании. А у WebBrowser-а есть нормальный интерфейс (custom-часть). Ее можно и так вызывать. Вообще непонятно причем здесь вообще диспач и передача параметров?...


в wb control загружается страничка со скриптом, из которого через external дергаются функции контейнера этого контрола. так вот для обслуживания этого external и делается реализация invoke.
Re[7]: вернуть строку из Invoke (bcb)
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.01.02 09:42
Оценка:
Здравствуйте twask, Вы писали:

T>только мне вызывать из javascript надо.


Ну, и что? Параметры in, out javascript сам бвдет делать BY_REF.


T>в wb control загружается страничка со скриптом, из которого через external дергаются функции контейнера этого контрола. так вот для обслуживания этого external и делается реализация invoke.


А что мешает сделать dual-интерфейс и только лишь поправить преобразование byref-ов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.