<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; JScript: ссылка на SafeArray]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=5608&amp;type=atom" />
	<updated>2011-03-23T08:59:30Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=5608</id>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46702#p46702" />
			<content type="html"><![CDATA[<p>Итог - Сегодня сделал пару тестов на VB 6. ) Добиться необходимого результата возможно. Но смысла не имеет. Проще сделать свою обёртку COM на COM объект разработчиков. )</p>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2011-03-23T08:59:30Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46702#p46702</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46608#p46608" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2011-03-22T19:03:24Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46608#p46608</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46603#p46603" />
			<content type="html"><![CDATA[<p>А, ну если GetData делает копию самих чисел массива, тогда конечно.</p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2011-03-22T18:50:08Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46603#p46603</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46600#p46600" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2011-03-22T18:29:09Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46600#p46600</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46597#p46597" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2011-03-22T18:24:39Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46597#p46597</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46594#p46594" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2011-03-22T18:09:44Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46594#p46594</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46590#p46590" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2011-03-22T17:56:26Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46590#p46590</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46585#p46585" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2011-03-22T17:20:41Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46585#p46585</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46581#p46581" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2011-03-22T16:46:29Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46581#p46581</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46578#p46578" />
			<content type="html"><![CDATA[<p>Может быть имеет смысл на VBScript перевести код?</p>]]></content>
			<author>
				<name><![CDATA[JSmаn]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24434</uri>
			</author>
			<updated>2011-03-22T16:14:06Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46578#p46578</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46574#p46574" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2011-03-22T14:53:03Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46574#p46574</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46564#p46564" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2011-03-22T14:02:37Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46564#p46564</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46556#p46556" />
			<content type="html"><![CDATA[<p>Посмотрите мой пост выше. Возможно вариант на VB 6 Вам подойдёт. Если нужно - могу скомпилить. Но тогда опять же нужны подробности. Хранилище даром не нужно, а вот на ActiveX я всё таки хотел бы &quot;посмотреть&quot;.</p>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2011-03-22T10:48:54Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46556#p46556</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46554#p46554" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[dolu]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=26834</uri>
			</author>
			<updated>2011-03-22T10:26:16Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46554#p46554</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript: ссылка на SafeArray]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46553#p46553" />
			<content type="html"><![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>]]></content>
			<author>
				<name><![CDATA[Xameleon]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=8836</uri>
			</author>
			<updated>2011-03-22T10:08:44Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46553#p46553</id>
		</entry>
</feed>
