PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Импорт строковой функции


Импорт строковой функции

Сообщений 1 страница 29 из 29

1

Есть библиотека (x32), там три функции. Две возвращают строки.
Это функции специально для Пурика написаны на FASM (переделаны после компиляции с /commented).
Вот как заставить PB понять, что функция возвращает строку?

Код:
EnableExplicit
Import "iif.lib"
  iif(c,a,b) ; Эта работает правильно
  ;iifs.s(c,a.s,b.s) ; Это даёт ошибку, а без .s работает не правильно
  iifs(c,a.s,b.s) ; Естественно, работает не правильно
  ;iif$(c,a.s,b.s) ; Это даёт ошибку
EndImport
Import "StringManager.lib" : EndImport ; Без этого никак
Debug iif(0,12345,67890)
Debug iifs(1,"QWERTYUIOP","ASDFGHJKL")
Debug "ZXCV<"+iifs(1,"QWERTYUIOP","ASDFGHJKL")+">"

Подозреваю, что облом, но вдруг...
https://disk.yandex.ru/d/nw8gVNn6ekqwrA

0

2

Код:
EnableExplicit
Import "iif.lib"
  iif(c,a,b) ; Эта работает правильно
EndImport

Debug PeekS(iif(0,12345,67890))

0

3

Пётр
Криво. Теряется смысл именно строковой функции. И я не уверен, что так правильно и не будет, скажем, утечки памяти. Ведь в случае строковой функции PB знает об этом, что память под строку была выделена и потом её надо освободить. А здесь получается освобождать не надо, ведь функция вроде как не строку возвращает. Но память то под неё была выделена!

П.С.
И я исхожу из того, что в Вашем примере ошибка, подразумевалась iifs.

Отредактировано Smitis (07.09.2023 09:44:24)

0

4

Smitis написал(а):

Ведь в случае строковой функции PB знает об этом, что память под строку была выделена и потом её надо освободить.

Все не так просто.
Неизвестно на чем написана lib-а и как выделена память под строку, а значит неизвестно как освобождать и нужно ли вообще это делать.

Smitis написал(а):

Но память то под неё была выделена!

Значит нужно в либу добавить функцию освобождения памяти

Код:
EnableExplicit
Import "iif.lib"
  iifs(c,a.s,b.s)
  MemFree(*p)
EndImport

Define *p = iifs(1,"QWERTYUIOP","ASDFGHJKL")
If *p
  Debug PeekS(*p)
  MemFree(*p)
EndIf

0

5

Пётр написал(а):

Неизвестно на чем написана lib-а и как выделена память под строку

Да я вроде написал - на PureBasic. Через /commented получен asm, из него выброшено лишнее, получились такие функции. Поэтому там с выделением памяти всё в порядке. С освобождением непонятно. И как НОРМАЛЬНО использовать возвращаемую строку без костылей.
Сами эти функции это так, чисто для примера. Была мысль написать вспомогательную утилиту для генерации библиотек lib из исходников pb. Собственно, в черне набросал быстро, засада со строковыми функциями. Если их нормально использовать не получится, то и создание библиотеки как таковой теряет смысл, ибо кому нужно такое костыльное творчество.
Видимо, не судьба.

0

6

Smitis написал(а):

Да я вроде написал - на PureBasic.

Официально PB не позволяет создавать статические либы и поэтому механизм передачи строки не предусмотрен. Но он есть в пользовательских библиотеках (те что создаются в TailBite).

Чем модули не устроили?

0

7

Пётр

Пётр написал(а):

Чем модули не устроили?

Не понял вопроса. Речь о модулях PB? А какое они имеют отношение к статическим либам?

0

8

Smitis написал(а):

Речь о модулях PB? А какое они имеют отношение к статическим либам?

Если либа будет вызываться из PB, то нет большой разницы использовать модуль или либу.
А если не из PB, то какая разница есть ли возможность импортировать строковую функцию?

0

9

Пётр
Честно говоря, я Вас не понимаю. Не верю, что специалист вроде Вас не видит разницы. Может быть Вам и всё равно, но мне нет. Есть либы, это скомпилированный код. Есть текст на PB, это НЕ скомпилированный код, и без разницы, оформлен он в виде модуля и нет. Модуль это всего лишь логическая организация программы. Можно и без либ обойтись, да. Хотя сам PB либы, как бы это странно не показалось, содержит. Вот и я задумал держать часть кода, который практически не изменяется, в либах. Потому что в некоторых случаях это удобнее, я бы таким образом избавился бы в своём проекте PurePortable от части условной компиляции, чтобы не тянуть лишний код и не допустить безмерного разрастания dll - пусть линковщик разбирается. Компилятор PB, конечно, частично оптимизирует код и может избавиться от неиспользуемой процедуры, но делает это не всегда корректно (оставляет код).

Отредактировано Smitis (07.09.2023 22:30:46)

0

10

Проблема либ на PB в их несовместимости между версиями. То есть если собрать либу скажем в 5.73, то в 6.02 или другой версии с большой долей вероятности получим ошибку компиляции.
Это давно проходили когда были популярны юзерлибы, создаваемые в TailBite.

Smitis написал(а):

таким образом избавился бы в своём проекте PurePortable от части условной компиляции, чтобы не тянуть лишний код и не допустить безмерного разрастания dll - пусть линковщик разбирается.

Для этого нужно каждую процедуру компилировать в отдельный объектник и после из них собирать либу.

0

11

Пётр написал(а):

Проблема либ на PB в их несовместимости между версиями.

Вот это уже проблема. Завтра проверю.

Для этого нужно каждую процедуру компилировать в отдельный объектник и после их них собирать либу.

Естественно, но это как раз оказалось не трудно. Процедуру можно вытянуть из purebasic.asm со всеми нужными внешними ссылками и скомпилировать отдельно.

0

12

я бы таким образом избавился бы в своём проекте PurePortable от части условной компиляции, чтобы не тянуть лишний код и не допустить безмерного разрастания dll - пусть линковщик разбирается. Компилятор PB, конечно, частично оптимизирует код и может избавиться от неиспользуемой процедуры, но делает это не всегда корректно (оставляет код).

Статические библиотеки наоборот код раздувают: функции уже скомпилированы и не допускают встраивания (inline).
Когда у компилятора есть исходник функции, то оптимизатор такую функцию может встроить. В результате в исполняемом файле вообще не будет никаких инструкций call и ret.

0

13

Замабувараев написал(а):

Статические библиотеки наоборот код раздувают: функции уже скомпилированы и не допускают встраивания (inline).
Когда у компилятора есть исходник функции, то оптимизатор такую функцию может встроить. В результате в исполняемом файле вообще не будет никаких инструкций call и ret.

Я думаю, для FASM-backend это не актуально. Для C-backend, может быть.

0

14

Пётр написал(а):

Проблема либ на PB в их несовместимости между версиями. То есть если собрать либу скажем в 5.73, то в 6.02 или другой версии с большой долей вероятности получим ошибку компиляции.
Это давно проходили когда были популярны юзерлибы, создаваемые в TailBite.

Для этого нужно каждую процедуру компилировать в отдельный объектник и после из них собирать либу.

А что это даёт в итоге?разве либа это не тупо машинный код с своими ссылками на процедуры(куски кода)?

Замабувараев написал(а):

Статические библиотеки наоборот код раздувают: функции уже скомпилированы и не допускают встраивания (inline).
Когда у компилятора есть исходник функции, то оптимизатор такую функцию может встроить. В результате в исполняемом файле вообще не будет никаких инструкций call и ret.

так на сколько актульна сейчас память раздуть на 1 мегабайт допустим когда памяти вагон и тележка?
Что значит исходник функции?она как минимум может быть написана на сто петьдесят языках и скомпилена в машинный код(асмоскиевы инструкции при декомпеляции)
и почему "не будет никаких инструкций call и ret"если для этого машинный код заложен?(что проц скажет не хочу это делать?)
ps:надо подумать над вопросом Smitis может что и посимпотичнее появится вместо peeks()

Отредактировано Sergeihik (08.09.2023 16:18:22)

0

15

Sergeihik написал(а):

так на сколько актульна сейчас память раздуть на 1 мегабайт допустим когда памяти вагон и тележка?

Вот так вот все рассуждают, а потом жалуются, что Винда тормознутая, что программы стали в несколько раз больше, а функционала не прибавилось... ;)

и почему "не будет никаких инструкций call и ret"если для этого машинный код заложен?

https://ru.wikipedia.org/wiki/Встраивание_функций

0

16

Smitis написал(а):

Вот так вот все рассуждают, а потом жалуются, что Винда тормознутая, что программы стали в несколько раз больше, а функционала не прибавилось...

https://ru.wikipedia.org/wiki/Встраивание_функций

Какой функционал?если в программе что то не реализовано это одно,ну может быть винда как то морозит прямой доступ к процу и тормозит ход программных инструкций?
Не ужели не прав что в современных компах памяти вагон для кода?что нужно туда во вложение стороннее загрузить типа базы чтобы всю память грохнуть по месту?
по поводу второго постараюсь позже посмотреть о чём речь

Отредактировано Sergeihik (08.09.2023 17:26:24)

0

17

Sergeihik написал(а):

Какой функционал?если в программе что то не реализовано это одно,ну может быть винда как то морозит прямой доступ к процу и тормозит ход программных инструкций?

Ну я там смайлик поставил, типа...
Но в принципе верно. Все жалуются, что программы становятся всё более гигантскими, операционка уже на DVD5 без ухищрений не влезает. Процессоры всё быстрее, а скоростей так и нет.
https://ru.wikipedia.org/wiki/Закон_Вирта

0

18

Smitis написал(а):

Ну я там смайлик поставил, типа...
Но в принципе верно. Все жалуются, что программы становятся всё более гигантскими, операционка уже на DVD5 без ухищрений не влезает. Процессоры всё быстрее, а скоростей так и нет.
https://ru.wikipedia.org/wiki/Закон_Вирта

Посмотрю завтра,а поверил бы когда 15 лет назад на флешку 5 гигиов залетает за секунд 20?а вот когда винду грохнул  и типа не система а юзер хозяин такое оказалось...
ps: так что мы многе ещё не знаем.....

Отредактировано Sergeihik (08.09.2023 18:12:37)

0

19

Ради интереса проверил PB 5.62, 5.73, 6.02 (x32). Генерируются одинаковые asm-файлы. К вопросу о совместимости.
Безусловно, никто не гарантирует такой идеальной совместимости в дальнейшем... Но такие вещи и так никто никогда не гарантирует.

0

20

Smitis написал(а):

Ради интереса проверил PB 5.62, 5.73, 6.02 (x32). Генерируются одинаковые asm-файлы.

Попробуйте скомпилировать приложение в 6.02 используя либу собранную в 5.62.

0

21

Пётр написал(а):

Попробуйте скомпилировать приложение в 6.02 используя либу собранную в 5.62

5.62 отлично использует такие либы от 6.02
Заниматься маразмом и продолжать "комбинировать" версии не буду.
Код asm (для каждой процедуры в отдельности) генерируется ИДЕНТИЧНЫЙ. Понимаете? По буквам: И-д-е-н-т-и-ч-н-ы-й.
То-есть, если и будет какая-то разница, то только в генерации obj-файлов, из которых будет собрана библиотека.
Значит различия могут зависеть только от компилятора FASM.
Но FASM простой ассемблер. Там нет каких-то немыслимых оптимизаций кода, чтобы какие-то супер возможности новой версии сделали что-то несовместимое.
Генерируемый asm достаточно прост, всё прозрачно, нет никаких "извратов".
У меня в PurePortable и то извратов на порядок больше, но как минимум с 5.11 проблем с совместимостью не было.

0

22

А вам кто‐нибудь гарантирует что Abi компилятора и рантайма будет одинаковым от версии к версии?

0

23

Замабувараев
Естественно, никто не гарантирует. И я об этом уже написал. Но на данном этапе это не самая актуальная проблема.

П.С.
Гарантировать что-либо вообще бесполезно. Вот помрёт Фред (не дай бог) и что? И всё.
Есть такой PowerBasic. Автор - автор известного в своё время TurboBasic. После отказа Борланда заниматься бейсиком, права вернулись автору и он стал его развивать под другим именем. А потом раз и помер (автор). На самом интересном месте, когда должны должна была делаться версия x64. И всё. Там, вроде как и команда была, и выкупить кто-то пытался. Но компилятор тоже умер.
https://en.wikipedia.org/wiki/PowerBASIC

Отредактировано Smitis (09.09.2023 18:03:16)

0

24

Исходники не только у Фреда.

ЯП могут забросить даже крупные компании, как было с Vb у микрософта.

0

25

Пётр написал(а):

ЯП могут забросить даже крупные компании, как было с Vb у микрософта.

Вот и я о том же. Никто не даст гарантии.

0

26

Речь в вике о встраивании в том что вызов становится не через стек это даёт прирост скорости но этот кусок кода как бы как макрос пихается везде.
а у вас ret 12 как бы освободить стек от аргументов и сделать возврат из процедуры!
Ваш пример не работает потому что линковщик не линкует error
рабочая функция работает потому что простая а не рабочая как я понял память выделяется под строку и освобождается при выходе из процедуры(надо поизучать тот код)

Код:
;format MS COFF
;public _iif@12
 Procedure.i iif(c,a,b)
;_iif@12:
;!PS0 = 4
   
  !CMP    dword [esp+4],0;c
  !JE    _EndIf2
  !MOV    eax,dword [esp+8];a
  !JMP   EndProcedure1
!_EndIf2:
  !MOV    eax,dword [esp+12];b
  !JMP   _EndProcedure1
!_EndProcedureZero1:
  !XOr    eax,eax
!EndProcedure1:
  !RETn    12
EndProcedure

 Debug iif(0,12345,67890)
Код:
;format MS COFF
;public _iif@12
 Procedure.i iif(c,a,b)
;_iif@12:
;!PS0 = 4
   
  !CMP    dword [esp+4],0;c
  !JE    EndIf2
  !MOV    eax,dword [esp+8];a
  ;!JMP   EndProcedure1
  !RETn    12 ;выйти с процедуры
  
!EndIf2:
  !MOV    eax,dword [esp+12];b
  ;!JMP   _EndProcedure1
  !RETn    12 ;выйти с процедуры
  
  
 ; 
;!_EndProcedureZero1:не рабочая метка
;!XOr    eax,eax

;!EndProcedure1:
 ; !RETn    12
EndProcedure

Debug iif(0,12345,67890)

;примерно из википедии только на макросе а не с работой ликовщика по замене кода процедуры на этот кусок
Global _eax.i
Macro iif2(c,a,b)
  If c=0
    _eax=b
  Else
    _eax=a
  EndIf 
EndMacro
iif2(0,12345,67890)
Debug _eax
Код:
;!format MS COFF

;!extrn SYS_FastAllocateString

;!extrn _PB_StringBasePosition
;!extrn _SYS_CopyString@4
;!extrn PB_StringBase
;!extrn _SYS_FreeString@4
;!public _iifs@12
 Procedure.s iifs(c,a.s,b.s)
;_iifs@12:
  ;PS2=12
  !XOr    eax,eax
  !PUSH   eax
  !PUSH   eax
 ;===типа выделить память под строки 
  !MOV    edx,dword [esp+16];a
  !LEA    ecx,[esp+0];типа получить адрес на вершину стека где 0 в ячейке памяти?  mov dword ecx,esp
  !CALL   SYS_FastAllocateString
  
  !MOV    edx,dword [esp+20];b
  !LEA    ecx,[esp+4];адрес второй ячейки стека
  !CALL   SYS_FastAllocateString
  ;=========
  
  !CMP    dword [esp+12],0;c=0?
  !JE    EndIf4
  
  !MOV    edx,dword [esp]
  !PUSH   dword [_PB_StringBasePosition]
  !PUSH   edx
  !CALL  _SYS_CopyString@4
  !POP    eax
  !ADD    eax,[PB_StringBase]
  !JMP   EndProcedure3
  
!EndIf4:
  !MOV    edx,dword [esp+4]
  !PUSH   dword [_PB_StringBasePosition]
  !PUSH   edx
  !CALL  _SYS_CopyString@4
  !POP    eax
  !ADD    eax,[PB_StringBase]
  !JMP   EndProcedure3
  
;_EndProcedureZero3:;опять не рабочая меткв и код
 ; MOV    eax,[_PB_StringBasePosition]
 ; ADD    eax,[PB_StringBase]
 ; MOV    word [eax],0
  
!EndProcedure3:
  !PUSH   dword [esp]
  !CALL  _SYS_FreeString@4
  !PUSH   dword [esp+4]
  !CALL  _SYS_FreeString@4
  !ADD    esp,8
  !RETn   12
EndProcedure
Procedure.s iifs2(c,a.s,b.s);типа такого что ли? как бы строка на входе в аргументе зачем что то мудрить?
  If c=0
    ProcedureReturn b
  Else
    ProcedureReturn a
  EndIf
 EndProcedure 
  
Debug iifs2(1,"QWERTYUIOP","ASDFGHJKL")

Отредактировано Sergeihik (10.09.2023 11:04:33)

0

27

А раздел официального форума TailBite, это тоже создание lib?

0

28

TailBite создает статическую библиотеку, а после преобразовывает в формат библиотеки функций PB.

0

29

Полезная статья по теме. В частности глава 3.
https://metanit.com/c/patterns/

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Импорт строковой функции