<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: DllCall и правильный вызов функций.]]></title>
	<link rel="self" href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=12869&amp;type=atom" />
	<updated>2019-01-21T10:02:29Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.script-coding.com/viewtopic.php?id=12869</id>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=131466#p131466" />
			<content type="html"><![CDATA[<p>А возможно ли вызвать методы класса из dll?<br /></p><div class="codebox"><pre><code>§ imread()
Mat cv::imread 	( 	const String &amp;  	filename,
		int  	flags = IMREAD_COLOR 
	) 		
Python:
	retval	=	cv.imread(	filename[, flags]	)</code></pre></div><p><a href="https://docs.opencv.org/3.4.5/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">https://docs.opencv.org/3.4.5/d4/da8/gr … 7b3bbd3a56</a><br />Dll Export Viewer показывает:<br /></p><div class="codebox"><pre><code>class cv::Mat __cdecl cv::imread(class cv::String const &amp; __ptr64,int)</code></pre></div><p>Через NET Framework Interop (CLR, C#, VB) вообще dll не загружается - выводит ошибку.<br /><a href="https://www.autohotkey.com/boards/viewtopic.php?t=4633">https://www.autohotkey.com/boards/viewtopic.php?t=4633</a></p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2019-01-21T10:02:29Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=131466#p131466</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=131159#p131159" />
			<content type="html"><![CDATA[<p>В общем, это логично. Первые 4 аргумента в x64 передаются в регистрах процессора. Если структура занимает 48 бит, вы не можете её из регистра записать в память как 48 бит, по кр. мере не за одну инструкцию процессора. За одну придётся писать сразу 64 бита. А если структура, к примеру, расположена в самом конце буфера памяти, то вы выйдете на 16 бит за его конец и перезапишете там какие-то другие данные нулями. Если же она находится в конце страницы памяти, а следующая страница не была выделена, то, наверно, будет исключение доступа. Тут даже и попытка чтения, по идее, может его вызвать.</p><p>8, 16 и 32 бита разрешены, поскольку эти части 64-битного регистра можно использовать, как самостоятельные регистры. Например, в регистре RAX можно к ним обращаться, как AL, AX и EAX. Так что здесь вы лишнего писать не будете.</p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-13T12:23:43Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=131159#p131159</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=131145#p131145" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Malcev пишет:</cite><blockquote><p>такую структуру<br /></p><div class="quotebox"><blockquote><p>struct ST1 {<br />&nbsp; &nbsp; char c1;&nbsp; &nbsp;1<br />&nbsp; &nbsp; short s1;&nbsp; &nbsp;2<br />&nbsp; &nbsp; word w; 2<br />&nbsp; &nbsp; double d;&nbsp; &nbsp;8<br />};</p></blockquote></div><p>для 32 бит нужно передавать так?<br /></p><div class="codebox"><pre><code>&quot;int64&quot;, c1 | (s1 &lt;&lt; 8) | (w &lt;&lt; 24), &quot;double&quot; d</code></pre></div><p>А для 64 так?<br /></p><div class="codebox"><pre><code>&quot;int64&quot;, c1 | (s1 &lt;&lt; 16) | (w &lt;&lt; 32), &quot;double&quot; d</code></pre></div></blockquote></div><p>Для 64 бит нужно передавать ссылкой, так как размер ее не равен 8, 16, 32, or 64 bits.</p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2019-01-13T11:13:11Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=131145#p131145</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130861#p130861" />
			<content type="html"><![CDATA[<p>Нет, ссылки нету.</p><p>Сейчас проверил вот эту структуру в Visual C++.<br /></p><div class="codebox"><pre><code>
typedef struct tagRAWMOUSE {
    USHORT usFlags;
    union {
        ULONG ulButtons;
        struct  {
            USHORT  usButtonFlags;
            USHORT  usButtonData;
        };
    };
    ULONG ulRawButtons;
    LONG lLastX;
    LONG lLastY;
    ULONG ulExtraInformation;
} RAWMOUSE, *PRAWMOUSE, *LPRAWMOUSE;
</code></pre></div><p>Расстояние от начала структуры до ulButtons показывает 4 байта. Значит, выравнивание всё-таки есть и в x86. Видимо, верна моя догадка, что большинство структур так составлено, что выравнивание не требуется, поэтому и нет ошибок, даже если про него не думаешь.</p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-05T12:42:19Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130861#p130861</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130855#p130855" />
			<content type="html"><![CDATA[<p>А у вас есть ссылка на документацию, где написаны эти требования для передачи структур для x64 и для x86?<br />И если передавать x86 с выравниванием по границе типа, то будет ошибка?</p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2019-01-05T10:31:41Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130855#p130855</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130852#p130852" />
			<content type="html"><![CDATA[<p>Если структура передаётся по ссылке 32-битной WinAPI функции, то не нужно. По крайней мере я никогда этого не делал, и никаких проблем не было. А как там компиляторы внутри программ эти структуры передают, это нас не касается. Для нас важен внешний интерфейс, с которым мы только и имеем дело. А тут требование выравнивания есть только для x64.</p><p>Конечно, можно предположить, что все структуры для x86 WinAPI так организованы, что и выравнивать не надо. Ну, может быть. Я каждую специально на этот предмет не проверял. Но это только гипотеза. Надо смотреть конкретные примеры структур.</p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-05T10:21:46Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130852#p130852</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130851#p130851" />
			<content type="html"><![CDATA[<p>На оффоруме автор функции написал, что и в x32 и в x64 элементы структуры нужно выравнивать по границе типа.<br />Структура {char c;short s;} передается всегда как &quot;int&quot;, c | (s &lt;&lt; 16).<br />В википедии вроде также написано:<br /></p><div class="quotebox"><blockquote><p>struct MixedData<br />{<br />&nbsp; &nbsp; char Data1;<br />&nbsp; &nbsp; short Data2;<br />&nbsp; &nbsp; int Data3;<br />&nbsp; &nbsp; char Data4;<br />};</p><p>After compilation the data structure will be supplemented with padding bytes to ensure a proper alignment for each of its members:</p><p>struct MixedData&nbsp; /* After compilation in 32-bit x86 machine */<br />{<br />&nbsp; &nbsp; char Data1; /* 1 byte */<br />&nbsp; &nbsp; char Padding1[1]; /* 1 byte for the following &#039;short&#039; to be aligned on a 2 byte boundary<br />assuming that the address where structure begins is an even number */<br />&nbsp; &nbsp; short Data2; /* 2 bytes */<br />&nbsp; &nbsp; int Data3;&nbsp; /* 4 bytes - largest structure member */<br />&nbsp; &nbsp; char Data4; /* 1 byte */<br />&nbsp; &nbsp; char Padding2[3]; /* 3 bytes to make total size of the structure 12 bytes */<br />};</p></blockquote></div><p><a href="https://en.wikipedia.org/wiki/Data_structure_alignment">https://en.wikipedia.org/wiki/Data_structure_alignment</a></p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2019-01-05T10:02:15Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130851#p130851</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130833#p130833" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Malcev пишет:</cite><blockquote><p>Просто интересно такое поведение.</p></blockquote></div><p>Ну, видимо, MsgBox тоже использует память.</p><div class="quotebox"><cite>Malcev пишет:</cite><blockquote><p>Так всё-таки почему вы именно на 7 байт больше запрашивали буфер?</p></blockquote></div><p>Это максимум, на который может сдвинуться вперёд адрес при округлении. Ведь расстояние между круглыми адресами 8 байт.</p><div class="quotebox"><cite>Malcev пишет:</cite><blockquote><p>Кстати, на оффоруме функцию написали, правда для ahk2</p></blockquote></div><p>При том, что тема была про v1. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-04T09:11:54Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130833#p130833</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130830#p130830" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>YMP пишет:</cite><blockquote><p>а почему это важно?</p></blockquote></div><p>Просто интересно такое поведение.<br /></p><div class="quotebox"><cite>YMP пишет:</cite><blockquote><p>А это реальный случай?</p></blockquote></div><p>Не, выдуманный.<br />Так всё-таки почему вы именно на 7 байт больше запрашивали буфер?<br />Кстати, на оффоруме функцию написали, правда для ahk2:<br /><a href="https://github.com/HelgeffegleH/AHK-misc./tree/master/functions/dllcall_struct">https://github.com/HelgeffegleH/AHK-mis … all_struct</a></p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2019-01-04T07:43:53Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130830#p130830</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130827#p130827" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Malcev пишет:</cite><blockquote><p>И почему если мы раскомментируем msgbox то результат будет другим?</p></blockquote></div><p>Не знаю, а почему это важно?</p><div class="quotebox"><cite>Malcev пишет:</cite><blockquote><p>И создание адреса структуры кратного самому большому элементу необходимо только при посылании структуры как ссылки?</p></blockquote></div><p>Видимо. В отношении стека я об этом не слышал. Ячейки его и так выровнены.</p><div class="quotebox"><cite>Malcev пишет:</cite><blockquote><p>И например такую структуру для 32 бит нужно передавать так?</p></blockquote></div><p>А это реальный случай? Что-то я сомневаюсь. Как её передал бы компилятор С, я не знаю. В принципе, наверно, мог бы как угодно, поскольку ведь код той функции, которая эту структуру принимает и использует, тоже он пишет. Он может просто выделить достаточное место в стеке и записать её туда либо ближе к началу этого места, либо ближе к концу, либо посередине. Нам нет смысла гадать.</p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2019-01-03T15:32:56Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130827#p130827</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130813#p130813" />
			<content type="html"><![CDATA[<p>У меня получается адрес памяти всегда кратным A_PtrSize, при том для 32bit всегда некратным 8.<br />То есть адрес и так всегда будет кратен самому большому элементу в структуре для 64 бит, а для 32 бит, как вы сказали, это необязательно.<br />А почему вы прибавляете именно 7?<br />И почему если мы раскомментируем msgbox то результат будет другим?<br /></p><div class="codebox"><pre><code>sruct_size := 16
VarSetCapacity(v1, sruct_size + 7)
; msgbox % &amp;v1
pStruct := ((&amp;v1 + 7) &gt;&gt; 3) &lt;&lt; 3
msgbox % &amp;v1 &quot;`n&quot; pStruct</code></pre></div><p>И создание адреса структуры кратного самому большому элементу необходимо только при посылании структуры как ссылки?<br />И например такую структуру<br /></p><div class="quotebox"><blockquote><p>struct ST1 {<br />&nbsp; &nbsp; char c1;&nbsp; &nbsp;1<br />&nbsp; &nbsp; short s1;&nbsp; &nbsp;2<br />&nbsp; &nbsp; word w; 2<br />&nbsp; &nbsp; double d;&nbsp; &nbsp;8<br />};</p></blockquote></div><p>для 32 бит нужно передавать так?<br /></p><div class="codebox"><pre><code>&quot;int64&quot;, c1 | (s1 &lt;&lt; 8) | (w &lt;&lt; 24), &quot;double&quot; d</code></pre></div><p>А для 64 так?<br /></p><div class="codebox"><pre><code>&quot;int64&quot;, c1 | (s1 &lt;&lt; 16) | (w &lt;&lt; 32), &quot;double&quot; d</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2019-01-03T11:25:27Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130813#p130813</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130778#p130778" />
			<content type="html"><![CDATA[<p>А зачем байт добавлять? Если вы в трёхлитровую банку нальёте два литра, то надо ли добавлять третий пустой литр? <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /> Так же если вы трёхбайтную структуру передаёте как int, то и четвёртый байт там само собой будет. Функция же знает, что она получает и какую часть объёма int занимает полезная информация. Главное чтобы она лежала правильно. Для x64 с выравниванием, для x86 без выравнивания.</p><p>Если создаёте структуру, то опять же просто выделяете 4 байта памяти и располагаете char и short в правильных местах этого объёма.</p><p>Адрес проще всего подгонять под кратный восьми. Судя по моим экспериментам, VarSetCapacity на x64 и так всегда выдаёт адреса, кратные 8. На x86 вижу либо то же, либо иногда бывают кратные 4.</p><p>Если нужна стопроцентная гарантия, то запрашивайте буфер на 7 байт больше, чем нужно, потом к адресу переменной прибавляйте 7 и округляйте результат до 8. Этот адрес уже и используйте для структуры.</p><div class="codebox"><pre><code>
VarSetCapacity(v1, sruct_size + 7)
pStruct := ((&amp;v1 + 7) &gt;&gt; 3) &lt;&lt; 3
</code></pre></div><p>Сдвиг на 3 бита вправо равносилен целочисленному делению на 8 (с отбрасыванием остатка), влево — умножению на 8. На 3 потому, что 8 — это третья степень двойки, а биты же двоичные числа.</p><p>В cdecl аргументы в стеке размещаются точно так же, как в stdcall. Разница между ними в том, кто их потом оттуда убирает. В cdecl это делает вызвавший функцию код, а в stdcall сама эта функция.</p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2018-12-31T13:30:35Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130778#p130778</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130769#p130769" />
			<content type="html"><![CDATA[<p>Тогда отвечающий с оффорума ошибся, когда написал, что для cdecl&nbsp; нужно сдвигать на 16? А вы не могли бы привести пример, как добавить байт в конец, numput здесь же не поможет? И как создать адрес структуры памяти, кратный самому большому элементу?</p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2018-12-31T09:52:43Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130769#p130769</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130765#p130765" />
			<content type="html"><![CDATA[<p>Ну да, так и должно быть в x64. В x86 надо сдвинуть на 8.</p>]]></content>
			<author>
				<name><![CDATA[YMP]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=81</uri>
			</author>
			<updated>2018-12-31T04:03:34Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130765#p130765</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: DllCall и правильный вызов функций.]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=130763#p130763" />
			<content type="html"><![CDATA[<p>А разве если мы делаем такую операцию &quot;int&quot;, c | (s &lt;&lt; 16), мы не получаем, что 1 байт занимает char, потом идет пустой байт, а потом 2 байта short?</p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2018-12-30T23:37:58Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=130763#p130763</id>
		</entry>
</feed>
