Передача аргумента [in,out] VARIANT* из JScript
От: Shire  
Дата: 18.06.03 12:22
Оценка:
Уважаемый All!

Вот тут мучил контрол MSWinsock.Winsock (поставляется с VB Ent. Edition) из JScript (WSH).
У него есть методы GetData и PeekData, которые принимают ссылку на VARIANT.

HRESULT xxxData(
    [in, out] VARIANT* data,
    [in, optional] VARIANT type,
    [in, optional] VARIANT maxLen);


Из VBScript всё замечательно, а JScript при передаче не изменяет переменную. Есть ли способ передать переменную на JScript, кроме написания своего переходника?
Если интересно, то код:

client.vbs:
dim bConnected
dim bSent
    bConnected=false
    bSent=false
dim    bDataReceived
    bDataReceived=false
dim    winsock
    Set winsock=WScript.CreateObject("MSWinsock.Winsock")
sub winsock_Connect
    WScript.Echo "Connected!"
    bConnected=true
end sub
sub winsock_SendComplete
    WScript.Echo "Sent!"
    bSent=true
end sub

sub winsock_DataArrival(bytTotal)
    WScript.Echo "Received:"
    WScript.Echo bytTotal
dim str
    winsock.GetData str,8 ' Всё замечательно!
    WScript.Echo str
    bDataReceived=true
end sub

    WScript.ConnectObject winsock,"winsock_"
    winsock.Connect "127.0.0.1",6789
    do while not (bConnected)
        WScript.Sleep 500
    Loop
    winsock.SendData "Client request..."
    do while not(bDataReceived)
        WScript.Sleep 500
    Loop
    winsock.Close


server.js

var    winsock=WScript.CreateObject("MSWinsock.Winsock");
var bClose=true;
function wsock_ConnectionRequest(reqId)
{
    WScript.Echo("accepting request");
    winsock.Close();
    winsock.Accept(reqId);
}
function wsock_DataArrival(bytTotal)
{
    WScript.Echo("Received:");
var    data="";
    WScript.Echo(bytTotal);
    winsock.GetData(data,8,bytTotal);// {вырезано цензурой} 
    WScript.Echo(data);
    winsock.SendData("Server response...");
}
function wsock_Error(number, desc, sCode, src, help, helpctx, cancelDisplay)
{
    WScript.Echo("Error: "+desc);
    bClose=false;
}
function wsock_Close()
{
    WScript.Echo("Connection closed.");
    bClose=false;
}
    WScript.ConnectObject(winsock,"wsock_");
    winsock.LocalPort=6789;
    winsock.Protocol=0;
    winsock.Listen();
    while(bClose)WScript.Sleep(500);


client.js

var bConnected=false;
var bSent=false;
var    bDataReceived=false;
var    winsock=WScript.CreateObject("MSWinsock.Winsock");
function wsock_Connect()
{
    WScript.Echo("Connected!");
    bConnected=true;
}
function wsock_SendComplete()
{
    WScript.Echo("Sent!");
    bSent=true;
}
function wsock_DataArrival(bytTotal)
{
    WScript.Echo("Received:");
    WScript.Echo(bytTotal);
var str=null;
    winsock.GetData(str,8);// {вырезано цензурой} 
    WScript.Echo(str);
    bDataReceived=true;
}
    WScript.ConnectObject(winsock,"wsock_");
    winsock.Connect("127.0.0.1",6789);
    while(!bConnected)WScript.Sleep(500);
    winsock.SendData("This is message!");
//    while(!bSent)WScript.Sleep(500);
    while(!bDataReceived)WScript.Sleep(500);
    winsock.Close();
Re: Передача аргумента [in,out] VARIANT* из JScript
От: folk Россия  
Дата: 19.06.03 22:53
Оценка:
Здравствуйте, Shire, Вы писали:

S>Уважаемый All!


S>Вот тут мучил контрол MSWinsock.Winsock (поставляется с VB Ent. Edition) из JScript (WSH).

S>У него есть методы GetData и PeekData, которые принимают ссылку на VARIANT.

S>
S>HRESULT xxxData(
S>    [in, out] VARIANT* data,
S>    [in, optional] VARIANT type,
S>    [in, optional] VARIANT maxLen);
S>


S>Из VBScript всё замечательно, а JScript при передаче не изменяет переменную. Есть ли способ передать переменную на JScript, кроме написания своего переходника?


Вот и у меня вчера похожая ситуация была.
При обращении к ActiveX-у интерпретатор JScript всегда передает ему VARIANT-копии аргументов (даже если это строка, а массивы я не пробовал), которые затем уничтожает. Т.е. трактует все аргументы как in.
Получается вот такое синтаксическое западло, что я могу вернуть только retval, т.е. не могу вернуть из метода более одного параметра.
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Скрипты и [out] параметры COM-методов
От: Vi2 Удмуртия http://www.adem.ru
Дата: 20.06.03 04:25
Оценка: 29 (2) +1
#Имя: FAQ.scripting.outparams
Здравствуйте, Shire, Вы писали:

S>Вот тут мучил контрол MSWinsock.Winsock (поставляется с VB Ent. Edition) из JScript (WSH).
S>У него есть методы GetData и PeekData, которые принимают ссылку на VARIANT.

S>HRESULT xxxData([in, out] VARIANT* data,[in, optional] VARIANT type,[in, optional] VARIANT maxLen);

S>Из VBScript всё замечательно, а JScript при передаче не изменяет переменную. Есть ли способ передать переменную на JScript, кроме написания своего переходника?


Начнем с того, что описание xxxData из IDL — это для умных клиентов, к которым ни VBScript, ни JScript причислить трудно.

Потому как они работают только с IDispatch интерфейсом и только так, как написано при вызове метода в их выражении. Правда, немного добавляя своих гадостей при передаче параметров через Invoke.

VBScript передает свои параметры как Variant, ссылающийся на другой Variant, содержащий реальное значение. Такой способ передачи допускает изменение входного параметра, даже если в IDL описании он — только [in].

JScript передает свои параметры как Variant, содержащий реальное значение. Такой способ передачи НЕ допускает изменение входного параметра, даже если в IDL описании он — [in,out].

Такие дела. Это просто нужно учитывать при написании объекта.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Это эффект IDispatch::Invoke
От: folk Россия  
Дата: 20.06.03 05:10
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, Shire, Вы писали:


Vi2>

S>>Вот тут мучил контрол MSWinsock.Winsock (поставляется с VB Ent. Edition) из JScript (WSH).
S>>У него есть методы GetData и PeekData, которые принимают ссылку на VARIANT.
Vi2>

S>>HRESULT xxxData([in, out] VARIANT* data,[in, optional] VARIANT type,[in, optional] VARIANT maxLen);
Vi2>

S>>Из VBScript всё замечательно, а JScript при передаче не изменяет переменную. Есть ли способ передать переменную на JScript, кроме написания своего переходника?

Vi2>Начнем с того, что описание xxxData из IDL — это для умных клиентов, к которым ни VBScript, ни JScript причислить трудно. Потому как они работают только с IDispatch интерфейсом и только так, как написано при вызове метода в их выражении. Правда, немного добавляя своих гадостей при передаче параметров через Invoke.

Vi2>VBScript передает свои параметры как Variant, ссылающийся на другой Variant, содержащий реальное значение. Такой способ передачи допускает изменение входного параметра, даже если в IDL описании он — только [in].


Vi2>JScript передает свои параметры как Variant, содержащий реальное значение. Такой способ передачи НЕ допускает изменение входного параметра, даже если в IDL описании он — [in,out].


Не согласен с этим пунктом.
Технически ничто не мешает JScript получить обратно переданные параметры. Ведь эти VARIANTы реально по указателю передаются, и JScript должен сам освободить их.
Видимо такое соглашение принято в целях безопасности, чтобы сервер чего не повредил клиенту... Хотя странно это.

Vi2>Такие дела. Это просто нужно учитывать при написании объекта.
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[3]: Это эффект IDispatch::Invoke
От: Vi2 Удмуртия http://www.adem.ru
Дата: 20.06.03 06:29
Оценка:
Здравствуйте, folk, Вы писали:

Vi2>>JScript передает свои параметры как Variant, содержащий реальное значение. Такой способ передачи НЕ допускает изменение входного параметра, даже если в IDL описании он — [in,out].
F>Не согласен с этим пунктом.
F>Технически ничто не мешает JScript получить обратно переданные параметры. Ведь эти VARIANTы реально по указателю передаются, и JScript должен сам освободить их.
F>Видимо такое соглашение принято в целях безопасности, чтобы сервер чего не повредил клиенту... Хотя странно это.

JScript тут не причем. Есть маршаллер IDispatch интерфейса. Он маршаллит параметры своих методов. В частности, параметр pDispParams метода Invoke. Причем варианты, не имеющие VT_BYREF, передаются только на сервер, а имеющие VT_BYREF — передаются обратно в клиент. Это не зависит от того, устанавливает ли или нет VT_BYREF сервер, ибо эти параметры подконтрольны при передаче.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[4]: Это эффект IDispatch::Invoke
От: Shire  
Дата: 20.06.03 11:05
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>

Vi2>>>JScript передает свои параметры как Variant, содержащий реальное значение. Такой способ передачи НЕ допускает изменение входного параметра, даже если в IDL описании он — [in,out]

.


Получается: при проектировании интерфейсов для использования в JScript нельзя использовать параметры c атрибутом out, кроме retval?
Уж очень неохота на vbScript переползать
Re[5]: Функции самого JScript-а
От: Vi2 Удмуртия http://www.adem.ru
Дата: 20.06.03 12:42
Оценка:
Здравствуйте, Shire, Вы писали:

S>Получается: при проектировании интерфейсов для использования в JScript нельзя использовать параметры c атрибутом out, кроме retval? Уж очень неохота на vbScript переползать

Я не знаком подробно с JScript, поэтому точно не могу сказать. Но лучше бы у JScript-щиков узнать: "Можно ли изменить параметр в функции самого JScript-а (т.е. описанной в JScript, а не в объекте), как, допустим, можно в самом VBScript-е указанием ByRef или ByVal?" Возможно, существуют способы задествовать косвенность.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[6]: Функции самого JScript-а
От: dimzon Россия http://dimzon541.narod.ru
Дата: 21.06.03 13:30
Оценка:
Здравствуйте, Vi2, Вы писали:


Vi2>Я не знаком подробно с JScript, поэтому точно не могу сказать. Но лучше бы у JScript-щиков узнать: "Можно ли изменить параметр в функции самого JScript-а (т.е. описанной в JScript, а не в объекте), как, допустим, можно в самом VBScript-е указанием ByRef или ByVal?" Возможно, существуют способы задествовать косвенность.


Нет, нельзя, это извесное ограничение JavaScript, его надо учитывать, JavaScript не совсем хорошо поддерживает COM Automation, также от не может например работать с нормальными массивами (которые в C++ SAFE_ARRAY), его родные массивы это его внутренние объектики. Кароче JScript — must die, VBScript рулит
... << RSDN@Home 1.0 beta 7a >>
Re[6]: Функции самого JScript-а
От: Блудов Павел Россия  
Дата: 09.11.04 05:21
Оценка: 4 (1)
Здравствуйте, Vi2, Вы писали:

Vi2>Я не знаком подробно с JScript, поэтому точно не могу сказать. Но лучше бы у JScript-щиков узнать: "Можно ли изменить параметр в функции самого JScript-а (т.е. описанной в JScript, а не в объекте), как, допустим, можно в самом VBScript-е указанием ByRef или ByVal?" Возможно, существуют способы задествовать косвенность.


В JScripte, если нужно вернуть ровно одно значение, его нужно просто возвращать как retval.
Если нужно вернуть более одного значения, можно создать объект, реализующий IDispatchEx, выставить ему столько свойств, сколько нужно и вернуть его в скрупт.

Описание метода будет таким:
interface ISmthDisp : IDispatch
{
    [propget, id(DISPID_PROP_BLABLA)]
        HRESULT blabla([out, retval] IDispatch* *ppBlabla);
};


Реализация такая:

STDMETHODIMP CSmthDispImpl::get_blabla
    ( OUT IDispatch* *ppBlabla
    )

{
    CoDispExSimpleObject        *pObject;
    ATL::CComVariant        varProp;
    HRESULT                hr;


    hr = CoDispExSimpleObject::CreateInstance(&pObject);
    if (SUCCEEDED(hr))
    {
        pObject->AddRef();

        varProp = 123;
        pObject->SetDispExProperty(PROP1_NAME, &varProp);

        varProp = OLESTR("far");
        pObject->SetDispExProperty(PROP2_NAME, &varProp);

        varProp = OLESTR("boo");
        pObject->SetDispExProperty(PROP3_NAME, &varProp);

        hr = pObject->QueryInterface(ppBlabla);

        pObject->Release();

    }

    return hr;
}


Ну а из скрипта этим можно будет пользоваться так:

var oBlabla = Application.blabla;
if (oBlabla.prop1 > 1)
{
    alert(oBlabla.prop2);
}
else
{
    alert(oBlabla.prop3);
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.