<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690287</guid>
        <pubDate>Tue, 25 Oct 2016 05:21:13 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690287</link>
        <description><![CDATA[Cfon: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3690281'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Виталь &#064; <time class="tag-quote__quoted-time" datetime="2016-10-24T19:44:39+00:00">24.10.16, 19:44</time></span><div class='quote '>P.S. я на С++ вынужден писать 2й раз в жизни, обычно Delphi хватало.</div></div><br>
это как? не изучая С++?  :huh: <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2016-10-25T08:22:03+03:00">25.10.16, 05:22</time></span></span><br>
просто сел и стал писать  :D <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2016-10-25T05:23:08+00:00">25.10.16, 05:23</time></span></span><br>
эх мне бы так  :(]]></description>
        <author>Cfon</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690281</guid>
        <pubDate>Mon, 24 Oct 2016 19:44:39 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690281</link>
        <description><![CDATA[Виталь: Всем спасибо, вопрос решил. Передается адрес буфера со статической длиной, хвост обрезается с помощью PAnsiChar.<br><br>P.S. я на С++ вынужден писать 2й раз в жизни, обычно Delphi хватало. Просто работал с такой ерундой импорты которой в D7 отсутствуют чуть менее чем полностью, а переписывать хедеры дело такое. Уже как-то раз пару лет назад переписывал Winsock на C# :tong: потому что у разработчиков API не хватило смелости выложить пример плагина на чем-то отличном от C# (хотя бы на C++, а там интерфейсы, COM объекты и прочая ерунда)]]></description>
        <author>Виталь</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690263</guid>
        <pubDate>Mon, 24 Oct 2016 10:26:42 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690263</link>
        <description><![CDATA[Cfon: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3690234'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>leo &#064; <time class="tag-quote__quoted-time" datetime="2016-10-24T05:01:11+00:00">24.10.16, 05:01</time></span><div class='quote '><strong class='tag-b'>MBo</strong> в #6 привел аналогичный вариант с array[..] of AnsiChar для дельфи-кода, который в основном и используется при получении строк из WinAPI.</div></div><br>
и это самый верный вариант, потому что WinAPI написана на Си, в далекие 80-е, когда они шли вместе с Паскалем рука об руку. <br>
ТС это азы виндос программиррования  :D <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2016-10-24T10:29:53+00:00">24.10.16, 10:29</time></span></span><br>
<strong class='tag-b'>Виталь</strong> начни уже читать книжки например &quot;Программирование для Windows 95&quot; Петзольда  :D <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2016-10-24T10:32:09+00:00">24.10.16, 10:32</time></span></span><br>
да да не удивляйся&#33; именно это древнее пособие для начинающих  :D<br>
ну а потом что-нибудь по сложнее, например Рихтера.]]></description>
        <author>Cfon</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690234</guid>
        <pubDate>Mon, 24 Oct 2016 05:01:11 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690234</link>
        <description><![CDATA[leo: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3690149'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>ЫукпШ &#064; <time class="tag-quote__quoted-time" datetime="2016-10-23T12:01:07+00:00">23.10.16, 12:01</time></span><div class='quote '>поэтому я и предлагал с самого начала использовать<br>
массив байт для передачи результата работы функции dll.</div></div><br>
Правильно. И <strong class='tag-b'>MBo</strong> в #6 привел аналогичный вариант с array[..] of AnsiChar для дельфи-кода, который в основном и используется при получении строк из WinAPI. При этом последующая конвертация полученного массива символов в string делается простым присваиванием s:=p1 (аналогичное пере-присваивание s:=PAnsiChar(s) <strong class='tag-b'>Виталь</strong> все равно вынужден делать для обрезки &quot;хвоста&quot; строки). А передача во внешнюю функцию PAnsiChar(s) используется сравнительно редко - в тех случаях, когда размер возвращаемой строки ничем не ограничен и м.б. любым&#092;большим (например, при чтении файла через TStringList.LoadFromFile сначала выделяется строка s под размер файла, в нее читаются данные, и затем делается ее разбивка на строки).<br>
<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3690149'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>ЫукпШ &#064; <time class="tag-quote__quoted-time" datetime="2016-10-23T12:01:07+00:00">23.10.16, 12:01</time></span><div class='quote '>Не исключено, что в Дельфи существуют библиотечные средства<br>
для работы со строками С</div></div><br>
Есть, но они непривычны и неудобны по сравнению с дельфийской string. Поэтому после возврата строки в массив buf, его обычно сразу копируют в string простым присваиванием s:=buf.]]></description>
        <author>leo</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690176</guid>
        <pubDate>Sun, 23 Oct 2016 15:24:55 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690176</link>
        <description><![CDATA[Cfon: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3690121'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>leo &#064; <time class="tag-quote__quoted-time" datetime="2016-10-23T09:24:21+00:00">23.10.16, 09:24</time></span><div class='quote '>В принципе оно и при strcpy может выскочить, если компилятор разместит литерал в read only памяти - возможно такое или нет, пусть спецы по стандартам C/C++ ответят.</div></div><br>
да именно так  :D]]></description>
        <author>Cfon</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690149</guid>
        <pubDate>Sun, 23 Oct 2016 12:01:07 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690149</link>
        <description><![CDATA[ЫукпШ: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3690121'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>leo &#064; <time class="tag-quote__quoted-time" datetime="2016-10-23T09:24:21+00:00">23.10.16, 09:24</time></span><div class='quote '>Поэтому не стоит удивляться тому, что при вызове strcat возникает AV. В принципе оно и при strcpy может выскочить, если компилятор разместит литерал в read only памяти - возможно такое или нет, пусть спецы по стандартам C/C++ ответят.</div></div><br>
<strong class='tag-b'>leo</strong>, поэтому я и предлагал с самого начала использовать<br>
массив байт для передачи результата работы функции dll.<br>
Это наиболее универсальный &quot;объект&quot; для передачи данных вообще.<br>
А что именно потом с этим делать - на вкус автора.<br>
Можно и &quot;старую&quot; Паскальную строку сформировать, можно и &quot;новую&quot;.<br>
Можно и так оставить и выводить по-символьно.<br>
Не исключено, что в Дельфи существуют библиотечные средства<br>
для работы со строками С. Но предположим, их нет или нам не нравятся.<br>
Тогда берём любимый Паскально-строчный объект.<br>
Наследуемся от него, добавляем необходимые свойства и методы и получаем <br>
свой собственный строчный объект, который умеет манипулировать<br>
стоками С. Для начала хотя бы их преобразовывать в Паскальный эквивалент.]]></description>
        <author>ЫукпШ</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690121</guid>
        <pubDate>Sun, 23 Oct 2016 09:24:21 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690121</link>
        <description><![CDATA[leo: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3690062'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>ЫукпШ &#064; <time class="tag-quote__quoted-time" datetime="2016-10-22T17:25:45+00:00">22.10.16, 17:25</time></span><div class='quote '>Как я понял, cудя по результатам автора, происходит именно это</div></div><br>
По сути это, но размер строки хранится в нулевом байте только для паскалевских &quot;коротких строк&quot; (shortstring). Для &quot;длинных&quot; же дельфийских строк (string) длина хранится иначе (в виде int по отрицательному смещению от начала массива символов). <br>
<br>
Кроме того, также по отрицательному смещению хранится и число ссылок на строку (RefCnt) - в данном случае это важно, т.к. <strong class='tag-b'>Виталь</strong>, думая, что он <em class='tag-i'>&quot;чуть приблизился к разгадке&quot;</em>, на самом деле столкнулся с еще одной &quot;загадкой&quot;, причем как дельфи, так и Си. Речь идет о ссылках&#092;указателях на константные строки (литералы).<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">static char *myVAR1 = &quot;1110000000&quot;; //С/С++</div><div class="code_line">s:=&#39;asdasdsddadsadasdasdasdsddadsadasdasdasdsddadsadasdasdasdsddadsadasd&#39;; //дельфи</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
Заменив динамическую инициализацию строки через SetLength(), на константно-литеральную s:=&#39;...&#39; в общем случае можно нарваться на AV при вызове getvar, т.к. при этом s ссылается не на собственную копию строки в дин.памяти, а на литеральную константу, которая в зависимости от ситуации может размещаться компилятором как в RW памяти (в секции инициализированных данных), так и в read only (например, непосредственно в секции кода). При изменении строки штатными дельфийскими методами компилятор проверяет кол-во ссылок на строку - если оно не равно 1, то перед изменением создается уникальная копия строки (UniqueString) в динамической памяти. Это же относится и к ссылкам на литеральные константы, которые имеют специальное значение RefCnt = -1, и соотв-но при любой штатной попытке изменения такой строки компилятор создает копию литерала в дин.памяти. Но функция getvar ничего об этих дельфийских хитростях&#092;загадках не знает и соотв-но может нарваться на AV, если строка s будет ссылаться на константу в read only памяти.<br>
<br>
Похожая ситуация и в С-коде, т.к. переменная myVAR1 объявлена не как массив символов char[..], а как указатель char*, ссылающийся на литеральную константу, которая размещена неизвестно где. Поэтому не стоит удивляться тому, что при вызове strcat возникает AV. В принципе оно и при strcpy может выскочить, если компилятор разместит литерал в read only памяти - возможно такое или нет, пусть спецы по стандартам C/C++ ответят.]]></description>
        <author>leo</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690062</guid>
        <pubDate>Sat, 22 Oct 2016 17:25:45 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690062</link>
        <description><![CDATA[ЫукпШ: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3690059'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>MBo &#064; <time class="tag-quote__quoted-time" datetime="2016-10-22T17:05:01+00:00">22.10.16, 17:05</time></span><div class='quote '><strong class='tag-b'>ЫукпШ</strong><br>
&gt;Первый байт Паскальной строки - размер данных строки.<br>
Это старый формат турбопаскаля, который поддерживается, но почти не используется, и в данном случае он не при деле.</div></div><br>
Как я понял, cудя по результатам автора, происходит именно это.<br>
<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '><br>
Так заполняется Паскальная строка:<br>
        s:=&#39;asdasdsddadsadasdasdasdsddadsadasdasdasdsddadsadasdasdasdsddadsadasd&#39;;<br>
         getvar(Pchar(s),length(s));<br>
<br>
        writeln(&#39;getvar= &quot;&#39;,(s),&#39;&quot;&#39;); //pansichar<br>
<br>
</div></div><br>
В строку были изначально занесено некоторое количество байт.<br>
Часть из них было искажено dll-ю.<br>
Был скопирован и двоичный 0.<br>
Размер строки изменён не был.<br>
Поэтому на экране оказалось это:<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '><br>
Вот такой код выводит на экран<br>
1110000000 sadasdasdasdsddadsadasdasdasdsddadsadasdasdasdsddadsadasd<br>
</div></div>]]></description>
        <author>ЫукпШ</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690059</guid>
        <pubDate>Sat, 22 Oct 2016 17:05:01 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690059</link>
        <description><![CDATA[MBo: <strong class='tag-b'>ЫукпШ</strong><br>
&gt;Первый байт Паскальной строки - размер данных строки.<br>
Это старый формат турбопаскаля, который поддерживается, но почти не используется, и в данном случае он не при деле.]]></description>
        <author>MBo</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690030</guid>
        <pubDate>Sat, 22 Oct 2016 14:03:15 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3690030</link>
        <description><![CDATA[ЫукпШ: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3689991'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Виталь &#064; <time class="tag-quote__quoted-time" datetime="2016-10-21T23:40:28+00:00">21.10.16, 23:40</time></span><div class='quote '>Чуть приблизился к разгадке.</div></div><br>
Ты почитай про форматы строк Паскаля и С.<br>
И тогда действительно приблизишься к разгадке.<br>
---<br>
Первый байт Паскальной строки - размер данных строки.<br>
Выделенные байты для неё могут занимать до 256, но при этом<br>
данных может не быть совсем. (самый первый байт - это размер данных в строке)<br>
Значит надо что сделать ?<br>
---<br>
Как-то так:<br>
1. Указать ф-ии dll в качестве приёмника байт массив байт достаточного размера.<br>
В ксчестве &quot;предохранителя&quot; можно указать размер массива. Но для начала можно просто<br>
указать большой буфер. Да хоть 1М.<br>
2. Получили буфер с данными - это строка С, данные ограничены 0 с хвоста.<br>
3. Надо написать процедуру, которая определит количество символов от начала массива до двоичного 0.<br>
   Т.е. определим размер данных строки.<br>
4. после этого пропишем этот размер в первый байт Паскальной строки.<br>
   Если он, конечно, не превышает допустимое значение 255.<br>
   Видимо, как-то так:<br>
   s[0]:= Подсчитанная_Длина;<br>
5. Скопируем в строку все полученные байты из буфера. Начиная с индекса 1 (s[1]:=.., s[2]:=.., s[3]:=.. ....).<br>
   <br>
   Цикл на Паскале ты сможешь смастерить ?<br>
<br>
 <a class='tag-url' href='http://forum.pascal.net.ru/index.php?showtopic=2361' target='_blank'>какой-то форум про строки Паскаля</a>]]></description>
        <author>ЫукпШ</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3689991</guid>
        <pubDate>Fri, 21 Oct 2016 23:40:28 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3689991</link>
        <description><![CDATA[Виталь: Чуть приблизился к разгадке. Прототип свиснул в GetWindowText()<br>
<br>
Код библиотеки:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">static char *myVAR1 = &quot;1110000000&quot;;</div><div class="code_line">static char *myVAR2 = &quot;222&quot;;</div><div class="code_line">&nbsp;</div><div class="code_line">EXTERN_DLL_EXPORT BOOL getvar(LPSTR lpString, int nMaxCount)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;strcpy(lpString,myVAR1);</div><div class="code_line">&nbsp;&nbsp; &nbsp;return true;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">EXTERN_DLL_EXPORT BOOL MyFunction()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;strcpy(myVAR1,&quot;TEST&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;return false;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
Код на Delphi:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function MyFunction; stdcall; external &#39;my.dll&#39; name &#39;MyFunction&#39;;</div><div class="code_line">function getvar(lpString: PChar; nMaxCount: Integer): BOOL; stdcall; external &#39;my.dll&#39; name &#39;getvar&#39;;</div><div class="code_line">...</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; //if MyFunction then writeln(&#39;TRUE&#39;) else writeln(&#39;FALSE&#39;); &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; s:=&#39;asdasdsddadsadasdasdasdsddadsadasdasdasdsddadsadasdasdasdsddadsadasd&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; getvar(Pchar(s),length(s));</div><div class="code_line">&nbsp;&nbsp; &nbsp; writeln(&#39;getvar= &quot;&#39;,(s),&#39;&quot;&#39;); //pansichar</div></ol></div></div></div></div><br>
<br>
Проблема:<br>
Вот такой код выводит на экран<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>1110000000 sadasdasdasdsddadsadasdasdasdsddadsadasdasdasdsddadsadasd</div></div><br>
Т.е. первые байты заполняются нормально, далее ноль, хвост можно откусить функцией pansichar(). Однако, если вызвать MyFunction, которая должна заполнить myVAR1 myVAR2 реальными значениями - строка TEST в переменной НЕ ПОЯВЛЯЕТСЯ. Если вместо strcpy поставить strcat - Access Violation. Почему такой бред? Мне нужно запихнуть в нужные переменные значения во время вызова MyFunction()]]></description>
        <author>Виталь</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3689177</guid>
        <pubDate>Tue, 18 Oct 2016 05:26:07 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3689177</link>
        <description><![CDATA[leo: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3689154'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Виталь &#064; <time class="tag-quote__quoted-time" datetime="2016-10-17T20:05:41+00:00">17.10.16, 20:05</time></span><div class='quote '>Для передачи указателя в Delphi используется конструкция var s:string а не просто s:string</div></div><br>
Указателя на что? В дельфи тип string по сути представляет собой указатель char* на первый символ строки. Соотв-но var s:string это указатель на указатель, т.е. char**.<br>
<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3689154'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Виталь &#064; <time class="tag-quote__quoted-time" datetime="2016-10-17T20:05:41+00:00">17.10.16, 20:05</time></span><div class='quote '>С точки зрения Delphi, если параметр передается без var при его изменении внутри процедуры наружу эти изменения не выходят.<br>
Но, как ни странно, именно при такой конструкции у меня C++ библиотека правильно пишет контент по нужным адресам в памяти</div></div><br>
Ничего странного в этом нет. Во-первых, в общем случае &quot;наружу не выходят&quot; только изменения значения самого параметра, т.е. если параметр представляет собой (явный или неявный) указатель на что либо, то изменения этого указателя наружу не выйдут. Но память по этому указателю м.б. изменена и соотв-но &quot;выйдет наружу&quot;. Простой пример - дельфийские классы, наследники TObject, например TStringList: передавая его без var, ты не можешь передать наружу только изменения самого указателя на объект (например создать новый экземпляр или обнулить переданный). Но с переданным объектом ты можешь делать, что угодно, например, очистить список или заполнить его строками.<br>
Во-вторых, параметры типа string, ведут себя подобно другим указателям (нельзя изменить сам указатель, но при определенных условиях можно изменить содержимое памяти по этому указателю) с той разницей, что компилятор автоматически отслеживает попытки изменения содержимого строки &quot;штатными способами&quot; (через дельфийские строковые операторы и функции) и при наличии таких &quot;штатных&quot; изменений автоматически создает копию строки, чтобы изменение её содержимого не &quot;вышли наружу&quot;. Но, во-первых, эта копия создается не до вызова функции, а внутри самой дельфийской функции, во-вторых, содержимое строки можно изменить &quot;нештатными&quot; методами - через PChar или передачей строки в функции, принимающие указатель.<br>
Резюме: в external функцию MyFunction(param1, param2:string) строки передаются как указатели на первый символ строки, и т.к. эта функция не дельфийская и никаких авто-копий строк не создает, то все изменения содержимого строк передаются &quot;наружу&quot;.<br>
<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3689154'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Виталь &#064; <time class="tag-quote__quoted-time" datetime="2016-10-17T20:05:41+00:00">17.10.16, 20:05</time></span><div class='quote '>Я пытался объявить параметры функции как var либо как pchar либо pansistring - получаю ошибку и вылет,</div></div><br>
Var и pansistring это явно не то, а pchar должно работать в дельфях до 2009. Чтобы работало во всех версиях, нужно в дельфи объявлять строки как s1,s2:AnsiString и передавать в функцию как PAnsiChar(s1). Если не выходить за пределы выделенного размера строки, то всё должно работать (иначе бы ни один &quot;идеальный аналог&quot; из WinAPI типа GetVolumeInformation не работал бы).]]></description>
        <author>leo</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3689174</guid>
        <pubDate>Tue, 18 Oct 2016 01:51:10 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3689174</link>
        <description><![CDATA[MBo: &gt;С точки зрения Delphi, если параметр передается без var при его изменении внутри процедуры наружу эти изменения не выходят.<br>
<br>
Если функция Дельфийская, то компилятор делает в ней локальную копию, и работа внутри функции идёт уже с ней. Но С++ функция об этом не знает.<br>
<br>
&gt;Но, как ни странно, именно при такой конструкции у меня C++ библиотека правильно пишет контент по нужным адресам в памяти.<br>
<br>
Дельфийская строка - указатель на тело, на массив символов. Аргумент С++ функции объявлен именно так, поэтому она может прочитать символы и заменить их в пределах имеющихся данных<br>
<br>
&gt;Я пытался объявить параметры функции как var либо как pchar либо pansistring - получаю ошибку и вылет,<br>
<br>
Метод венгерского товарища Тыка работает плохо. Лучше разобраться. И убедись, что объявление в С соответствет STDCALL (это зависит от дефайнов)<br>
<br>
Если гарантировано, что длина возвращаемых строк не превышает 254 байта, при том же С-шном объявлении можно так:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;p1, p2: array[0..MAX_PATH] of AnsiChar; &nbsp;//память на стеке автоматически выделена</div><div class="code_line">&nbsp;</div><div class="code_line">p1[0] := #0;</div><div class="code_line">p2[0] := #0;</div><div class="code_line">if MyFunction(p1, p2)...</div><div class="code_line">//p1,p2 по многим операциям (присвоению) совмеcтимы со строками и PAnsiChar</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">EXTERN_DLL BOOL MyFunction(char *param1, char *param2)</div><div class="code_line">{</div><div class="code_line">//что-то выполняется</div><div class="code_line">strcat(param1, что-то здесь);</div><div class="code_line">strcat(param2, что-то здесь);</div><div class="code_line">return true;</div><div class="code_line">}</div></ol></div></div></div></div>]]></description>
        <author>MBo</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3689154</guid>
        <pubDate>Mon, 17 Oct 2016 20:05:41 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3689154</link>
        <description><![CDATA[Виталь: Не, смотрите в чем дело. Для передачи указателя в Delphi используется конструкция var s:string а не просто s:string<br>С точки зрения Delphi, если параметр передается без var при его изменении внутри процедуры наружу эти изменения не выходят.<br>Но, как ни странно, именно при такой конструкции у меня C++ библиотека правильно пишет контент по нужным адресам в памяти.<br>Это абсолютно не поддается логике но работает. Я пытался объявить параметры функции как var либо как pchar либо pansistring - получаю ошибку и вылет, причем не понимаю откуда эта ошибка может исходить<br><br>По размеру - должно влазить, я объявил строку на 150 знаков, в нее пишется порядка 10-20]]></description>
        <author>Виталь</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3689029</guid>
        <pubDate>Mon, 17 Oct 2016 09:37:13 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3689029</link>
        <description><![CDATA[ЫукпШ: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3688978'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>MBo &#064; <time class="tag-quote__quoted-time" datetime="2016-10-17T03:30:34+00:00">17.10.16, 03:30</time></span><div class='quote '>Дельфийские строки передавать в DLL нельзя (можно только на чтение), т.к. менеджеры памяти разные, а у тебя идёт модификация. Вылез за пределы 128 и всё...</div></div><br>
А причём тут манагер памяти ?<br>
Строки Паскаля и С (насколько я помню) разные по формату.<br>
Поэтому их нельзя использовать вместо друг друга.<br>
Можно посоветовать вместо указателя на Паскальную строку<br>
передать указатель на массив char.<br>
А дальше в Паскальной программе с ним разбираться.<br>
Фактически нужно будет преобразовать строку С в строку Паскаля.<br>
Либо переделать ф-ию в dll, чтобы в качестве результата<br>
она формировала именно Паскальную строку.]]></description>
        <author>ЫукпШ</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3688980</guid>
        <pubDate>Mon, 17 Oct 2016 04:41:31 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3688980</link>
        <description><![CDATA[leo: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=409739&view=findpost&p=3688970'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Виталь &#064; <time class="tag-quote__quoted-time" datetime="2016-10-16T21:58:51+00:00">16.10.16, 21:58</time></span><div class='quote '>Идеальный пример аналога - GetVolumeInformation()</div></div><br>
В &quot;идеальных примерах&quot; WinAPI кроме указателя на буфер строки также передается и его размер. Если требуемый размер превышает переданный, то функция либо 1) возвращает false, а GetLastError выдает что-то типа ERROR_INSUFFICIENT_BUFFER, либо 2) функция возвращает не BOOL, а код ошибки со значением &#33;= 0 (в этом случае возврат 0 означает ERROR_SUCCESS - успешное выполнение).]]></description>
        <author>leo</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3688978</guid>
        <pubDate>Mon, 17 Oct 2016 03:30:34 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3688978</link>
        <description><![CDATA[MBo: Дельфийские строки передавать в DLL нельзя (можно только на чтение), т.к. менеджеры памяти разные, а у тебя идёт модификация. Вылез за пределы 128 и всё...<br><br>Используй PAnsiChar. Память выдели с запасом, либо сделай, как во многих некоторых WinAPI-функциях - первый вызов с нулевой строкой рассчитывает размер и возвращает требуемое число байтов. Выделил память - вызывай смело.<br><br>Внутри сишной функции перераспределения памяти не делать. Если оно действительно необходимо, параметр придётся делать **char, а в Дельфи var PAnsiChar или PPAnsiChar.]]></description>
        <author>MBo</author>
        <category>C/C++: Прочее</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3688970</guid>
        <pubDate>Sun, 16 Oct 2016 21:58:51 +0000</pubDate>
        <title>Функция со строковым параметром в DLL для использования из Delphi</title>
        <link>https://forum.sources.ru/index.php?showtopic=409739&amp;view=findpost&amp;p=3688970</link>
        <description><![CDATA[Виталь: Доброго времени суток. Забрел к вам из соседнего раздела.<br>
Имею следующую проблему - есть код на С++, перевести его на Delphi сложно но использовать его нужно именно из ПО на Delphi.<br>
C знаю плохо. Код формально работает, но при некоторых обстоятельствах вызывает непредсказуемое поведение (работает на Delphi 7, не работает на некоторых других компиляторах - вылет ошибки или хлам в данных).<br>
Функция обязана выполниться и вернуть 2 строки. Идеальный пример аналога - GetVolumeInformation() которая возвращает имя тома и название файловой системы.<br>
<br>
Код DLL:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#define EXTERN_DLL extern &quot;C&quot; __declspec(dllexport)</div><div class="code_line">&nbsp;</div><div class="code_line">EXTERN_DLL BOOL MyFunction(char *param1, char *param2)</div><div class="code_line">{</div><div class="code_line">//обнуляю значения</div><div class="code_line">strcpy(param1,&quot;&quot;);</div><div class="code_line">strcpy(param2,&quot;&quot;);</div><div class="code_line">//что-то выполняется</div><div class="code_line">strcat(param1, что-то здесь);</div><div class="code_line">strcat(param2, что-то здесь);</div><div class="code_line">return true;</div><div class="code_line">//попутно в коде обработчики ошибок которые return false, тогда в param1 строка описание ошибки.</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
Вызываю из Delphi:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function MyFunction(param1, param2:string):bool; stdcall; external &#39;my.dll&#39; name &#39;MyFunction&#39;;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; s1,s2:string;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; setlength(s1,128);</div><div class="code_line">&nbsp;&nbsp; &nbsp; setlength(s2,128);</div><div class="code_line">&nbsp;&nbsp; &nbsp; if MyFunction(s1, s2) then writeln(&#39;TRUE&#39;) else writeln(&#39;FALSE&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; writeln(&#39;s1= &#39;,pansichar(s1));</div><div class="code_line">&nbsp;&nbsp; &nbsp; writeln(&#39;s2= &#39;,pansichar(s2));</div><div class="code_line">end;</div></ol></div></div></div></div><br>
За качество паскального кода не бить, работает оно только в этом виде при заранее установленных длинах строк. Любая попытка передачи PAnsiChar, var s:string и так далее приводила к тем или иным Access Violation. Тип функции stdcall, cdecl - проверялись оба. В варианте DLL когда экспортируется функция _MyFunction@8 то же самое.<br>
<br>
Прошу дать рабочий прототип C++ функции &quot;как оно должно быть на самом деле&quot; включая метод вызова strcpy, strcat для таких параметров (задолбался тыкать звездочки куда попало)]]></description>
        <author>Виталь</author>
        <category>C/C++: Прочее</category>
      </item>
	
      </channel>
      </rss>
	