<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; JScript: ссылка на SafeArray]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=5608</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=5608&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «JScript: ссылка на SafeArray».]]></description>
		<lastBuildDate>Wed, 23 Mar 2011 08:59:30 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46702#p46702</link>
			<description><![CDATA[<p>Итог - Сегодня сделал пару тестов на VB 6. ) Добиться необходимого результата возможно. Но смысла не имеет. Проще сделать свою обёртку COM на COM объект разработчиков. )</p>]]></description>
			<author><![CDATA[null@example.com (Xameleon)]]></author>
			<pubDate>Wed, 23 Mar 2011 08:59:30 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46702#p46702</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46608#p46608</link>
			<description><![CDATA[<p><strong>2 YMP:</strong> На сколько я знаю, <strong>GetData</strong> у <strong>spMemoryStream</strong>, равно как и функции <strong>Read</strong> у <strong>ADODB.Stream</strong>, да и <strong>Recordset.GetChunk</strong> отдают байтовые массивы копией. На VB 6.0 попробовал сделать у класс модуля публичный байтовый массив типа<br /></p><div class="codebox"><pre><code>Public Data() as Byte</code></pre></div><p>VB 6 такого не позволяет. Ругается на то, что типизированные данные нельзя так высовывать. Т.е байтовый массив можно отдать только через функцию или свойство.<br /></p><div class="codebox"><pre><code>Public Property Get Data() as Byte()
  &#039;Data = ....
End Property

Public Function GetData() as Byte()
  &#039;Data = ....
End Function</code></pre></div><p>Но такой подход подразумевает отдачу данных с копией массива.</p><p>Задумался над методом с Variant параметром<br /></p><div class="codebox"><pre><code>Public Sub Test(Data)
   Dim bData() as byte
   bData() = Data
   Data = bData
End Sub</code></pre></div><p>Пробовал вечером, возможно ошибся. Наружу получил &quot;пустоту&quot;. Проверял по MsgBox. Возможно не прав. Надо поизучать содержимое. Попробую завтра.</p>]]></description>
			<author><![CDATA[null@example.com (Xameleon)]]></author>
			<pubDate>Tue, 22 Mar 2011 19:03:24 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46608#p46608</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46603#p46603</link>
			<description><![CDATA[<p>А, ну если GetData делает копию самих чисел массива, тогда конечно.</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Tue, 22 Mar 2011 18:50:08 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46603#p46603</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46600#p46600</link>
			<description><![CDATA[<p>Каким образом ? </p><p>Если мы отдаём массив через <strong>spMemoryStream.GetData</strong> то он уходит в функцию безвозвратно. Т.к генерится копия в момент вызова метода и уже она отдаётся &quot;наружу&quot;.</p><p>Ошибаюсь ?</p><div class="codebox"><pre><code>Dim spMemoryStream, i, Data, retArray
Set spMemoryStream = CreateObject(&quot;SAPI.spMemoryStream&quot;)
For i=0 to 1000
    spMemoryStream.Write CByte(0)
Next

Obj.Read 0, spMemoryStream.GetData

retArray = spMemoryStream.GetData</code></pre></div><p>Т.е <strong>retArray</strong> получит исходный массив, который мы заполнили до вызова.</p><p>Или есть ещё варианты его заполучить ?</p>]]></description>
			<author><![CDATA[null@example.com (Xameleon)]]></author>
			<pubDate>Tue, 22 Mar 2011 18:29:09 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46600#p46600</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46597#p46597</link>
			<description><![CDATA[<div class="quotebox"><cite>Xameleon пишет:</cite><blockquote><p><strong>2 YMP:</strong> Вот я собственно поэтому и предположил, что передача напрямую &quot;пройдёт&quot;, но не будет иметь смысла, т.к связи с этим массивом мы уже иметь не будем. </p><p>Я правильно понимаю ? <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p></blockquote></div><p>Думаю, будем. По значению-то передаётся (копируется) не сам массив, а указатель на него.</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Tue, 22 Mar 2011 18:24:39 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46597#p46597</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46594#p46594</link>
			<description><![CDATA[<p><strong>2 YMP:</strong> Вот я собственно поэтому и предположил, что передача напрямую &quot;пройдёт&quot;, но не будет иметь смысла, т.к связи с этим массивом мы уже иметь не будем. </p><p>Я правильно понимаю ? <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p>]]></description>
			<author><![CDATA[null@example.com (Xameleon)]]></author>
			<pubDate>Tue, 22 Mar 2011 18:09:44 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46594#p46594</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46590#p46590</link>
			<description><![CDATA[<p>Да, в VBS разница есть. При &quot;прямой&quot; передаче Variant, переданный в Invoke, имеет тип VT_ARRAY | VT_UI1, т.е. он содержит указатель на первое число массива. При передаче через переменную имеем такую связку: VT_BYREF | VT_VARIANT —&gt; VT_ARRAY | VT_UI1, т.е. в Invoke передаётся Variant, содержащий указатель на другой Variant, который уже содержит указатель на первое число массива. Проще говоря, в первом случае происходит передача по значению (ByVal), а во втором по ссылке (ByRef).</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Tue, 22 Mar 2011 17:56:26 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46590#p46590</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46585#p46585</link>
			<description><![CDATA[<p><strong>2 YMP:</strong> Возник вопрос.</p><p>Решил протестировать на самодельном COM компоненте.</p><p>Создал <strong>Project1.Class1</strong> объект в VB6</p><p>С методом TestSub</p><div class="codebox"><pre><code>Sub TestSub(data() As Byte)
    MsgBox TypeName(data), vbInformation, &quot;TestSub&quot;
End Sub</code></pre></div><p>Написал скрипт<br /></p><div class="codebox"><pre><code>Test1

Test2

Sub Test1
    Dim spMemoryStream, i, Data
    Set spMemoryStream = CreateObject(&quot;SAPI.spMemoryStream&quot;)
    For i=0 to 1000
        spMemoryStream.Write CByte(0)
    Next

    Set P = CreateObject(&quot;Project1.Class1&quot;)
    P.TestSub spMemoryStream.GetData
End Sub

Sub Test2
    Dim spMemoryStream, i, Data
    Set spMemoryStream = CreateObject(&quot;SAPI.spMemoryStream&quot;)
    For i=0 to 1000
        spMemoryStream.Write CByte(0)
    Next

    Dim tmp
    tmp = spMemoryStream.GetData
    Set P = CreateObject(&quot;Project1.Class1&quot;)
    P.TestSub tmp
End Sub</code></pre></div><p>И как я и наблюдал ранее - Первая процедура отрабатывает, вторая &quot;падает&quot;. Из чего я когда то давно сделал вывод, что передача &quot;напрямую&quot; и через переменную отличается.</p><p>Поясните пожалуйста - я ошибаюсь ? <br /><a href="http://file.qip.ru/file/oTxR29FB/Test.html">http://file.qip.ru/file/oTxR29FB/Test.html</a></p><p>Исходник, скомпилированый вариант и тестовый скрипт, сложил по ссылке.</p>]]></description>
			<author><![CDATA[null@example.com (Xameleon)]]></author>
			<pubDate>Tue, 22 Mar 2011 17:20:41 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46585#p46585</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46581#p46581</link>
			<description><![CDATA[<p><strong>2 YMP:</strong><br /></p><div class="quotebox"><cite>YMP пишет:</cite><blockquote><div class="quotebox"><cite>Xameleon пишет:</cite><blockquote><p>Предполагаю, что передача напрямую пройдёт нормально, но при этом смысл такой передачи теряется. Т.к массив уйдёт напрямую в функцию и обратно мы его уже не получим.</p></blockquote></div><p>Что за передача напрямую? Скрипт с методами напрямую не работает. Он с ними работает через метод Invoke интерфейса IDispatch. В Invoke передаётся dispid нужного метода и его параметры в виде массива Variant&#039;ов. То, что Вы в скрипте не пишете значение в переменную, ничего не изменит.</p><p>Видимо, просто нужен Variant типа VT_SAFEARRAY, он и будет после передачи в Invoke корректно преобразован в массив байтов, который и будет передан методу. В JScript такого типа данных нет, и те объекты, что здесь испробованы, не его возвращают, а VT_ARRAY.</p></blockquote></div><p>Вот я как раз и ждал Вашего мнения коллега. ) Т.к всех тонкостей этого вопроса я не знаю. Изучал как говорится методом проб и ошибок. )</p><p><strong>2 JSman:</strong> К сожалению не помогло. Видимо ситуация немного сложнее.</p>]]></description>
			<author><![CDATA[null@example.com (Xameleon)]]></author>
			<pubDate>Tue, 22 Mar 2011 16:46:29 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46581#p46581</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46578#p46578</link>
			<description><![CDATA[<p>Может быть имеет смысл на VBScript перевести код?</p>]]></description>
			<author><![CDATA[null@example.com (JSmаn)]]></author>
			<pubDate>Tue, 22 Mar 2011 16:14:06 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46578#p46578</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46574#p46574</link>
			<description><![CDATA[<div class="quotebox"><cite>Xameleon пишет:</cite><blockquote><p>Предполагаю, что передача напрямую пройдёт нормально, но при этом смысл такой передачи теряется. Т.к массив уйдёт напрямую в функцию и обратно мы его уже не получим.</p></blockquote></div><p>Что за передача напрямую? Скрипт с методами напрямую не работает. Он с ними работает через метод Invoke интерфейса IDispatch. В Invoke передаётся dispid нужного метода и его параметры в виде массива Variant&#039;ов. То, что Вы в скрипте не пишете значение в переменную, ничего не изменит.</p><p>Видимо, просто нужен Variant типа VT_SAFEARRAY, он и будет после передачи в Invoke корректно преобразован в массив байтов, который и будет передан методу. В JScript такого типа данных нет, и те объекты, что здесь испробованы, не его возвращают, а VT_ARRAY.</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Tue, 22 Mar 2011 14:53:03 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46574#p46574</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46564#p46564</link>
			<description><![CDATA[<p>В результате исследования объекта было выяснено, что метод Read принимает ссылку на байтовый массив.<br /></p><div class="quotebox"><blockquote><p>Read(Offset As Double, Buffer() As Byte)</p></blockquote></div><p>В результате такой код:<br /></p><div class="codebox"><pre><code>Dim spMemoryStream, i, Data
Set spMemoryStream = CreateObject(&quot;SAPI.spMemoryStream&quot;)
For i=0 to 1000
    spMemoryStream.Write CByte(0)
Next

Data = spMemoryStream.GetData

Obj.Read 0, Data</code></pre></div><p>вызывает <strong>Type Mismatch</strong>. Из-за того, что байтовый массив укладывается в Varinat &quot;оболочку&quot; переменной <strong>Data</strong>.</p><div class="codebox"><pre><code>Dim spMemoryStream, i, Data
Set spMemoryStream = CreateObject(&quot;SAPI.spMemoryStream&quot;)
For i=0 to 1000
    spMemoryStream.Write CByte(0)
Next

Obj.Read 0, spMemoryStream.GetData</code></pre></div><p>Предполагаю, что передача напрямую пройдёт нормально, но при этом смысл такой передачи теряется. Т.к массив уйдёт напрямую в функцию и обратно мы его уже не получим.</p><p>Пока решено поэкспериментировать с промежуточным COM объектом.</p>]]></description>
			<author><![CDATA[null@example.com (Xameleon)]]></author>
			<pubDate>Tue, 22 Mar 2011 14:02:37 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46564#p46564</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46556#p46556</link>
			<description><![CDATA[<p>Посмотрите мой пост выше. Возможно вариант на VB 6 Вам подойдёт. Если нужно - могу скомпилить. Но тогда опять же нужны подробности. Хранилище даром не нужно, а вот на ActiveX я всё таки хотел бы &quot;посмотреть&quot;.</p>]]></description>
			<author><![CDATA[null@example.com (Xameleon)]]></author>
			<pubDate>Tue, 22 Mar 2011 10:48:54 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46556#p46556</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46554#p46554</link>
			<description><![CDATA[<div class="quotebox"><blockquote><p>Вы уверены, что пробовали именно так ?</p></blockquote></div><p>Да, только в VBScript так:</p><div class="codebox"><pre><code>Obj.Read 0, Data</code></pre></div><p>без скобок (ещё раз проверил... Type mismatch)</p><div class="quotebox"><blockquote><p>Если интерфейс хранилища оформлен в виде ActiveX COM, то Вам в 99% случаев не нужен никакой промежуточный объект.</p></blockquote></div><p>Золотые слова :-) я уже так намучился с этим промежуточным объектом...</p>]]></description>
			<author><![CDATA[null@example.com (dolu)]]></author>
			<pubDate>Tue, 22 Mar 2011 10:26:16 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46554#p46554</guid>
		</item>
		<item>
			<title><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=46553#p46553</link>
			<description><![CDATA[<div class="quotebox"><cite>dolu пишет:</cite><blockquote><p>Можно просто написать ActiveX компонент с одним объектом и методом, который требует параметр SAFEARRAY * * и попытаться ему его передать из скрипта. :-)</p></blockquote></div><p>Вы <span class="bbu">уверены</span>, что пробывали именно так ?</p><div class="codebox"><pre><code>Dim spMemoryStream, i, Data
Set spMemoryStream = CreateObject(&quot;SAPI.spMemoryStream&quot;)
For i=0 to 1000
    spMemoryStream.Write CByte(0)
Next

Data = spMemoryStream.GetData

Obj.Read 0, Data</code></pre></div><p>На выходе из <strong>GetData</strong> Вы получаете тот самый <strong>SafeArray</strong>.</p><p>P.S Если интерфейс хранилища оформлен в виде ActiveX COM, то Вам в 99% случаев не нужен никакой промежуточный объект.</p><p>----------------------------</p><p>Подумал.... Всё таки если так не сработает (и предположительно метод у COM объекта описан не совсем так как Вы написали), то возможно в той обёртке, которую Вы используете нужно получить указатель на первый элемент массива. К сожалению не владею знаниями о Delphi, поэтому предположу как это должно быть на <strong>Visual Basic 6.0</strong></p><p>Вам нужно получить указатель на первый элемент байтового массива <strong>VarPtr(arr(0))</strong></p><p>Значит метод у COM должен быть наподобии</p><div class="codebox"><pre><code>Public Sub SendByteArray(data)
      Dim b() as Byte
      b = data
      ApiObject.SomeMethod(0,VarPtr(b(0)))
End Sub</code></pre></div><p>Это в самом грубом варианте. Без проверок на типы данных и границы массива. В этом случае в SomeMethod уйдёт указатель типа <strong>Long</strong>. Сишные функции в массе своей именно так принимают массивы. Но ещё раз повторюсь - это предположение на случай если первый вариант не сработает. </p><p>И всё таки очень хотелось бы наладить связь через альтернативные средства обмена сообщениями. Так проще экспериментировать.</p>]]></description>
			<author><![CDATA[null@example.com (Xameleon)]]></author>
			<pubDate>Tue, 22 Mar 2011 10:08:44 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=46553#p46553</guid>
		</item>
	</channel>
</rss>
