Возврат указателя на строку производного типа из функции сторонней программе на C

Предыдущая тема Следующая тема Перейти вниз

Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Black Doomer в Ср Апр 18, 2012 5:21 am

И опять я со своими костылями.
Теперь у меня не получается передать результирующую строку обратно в программу.
Принимаемая переменная и результат у нас определены как String Ptr. Это необходимое условие, так как сторонняя программа для подключения библиотек использует вызовы с использованием типов Double (для чисел) и некий аналог дельфовского PChar для строк.
Стандартное объявление функции, совместимой с вызовами этой программы, выглядит так:
Код:
#define GME cdecl Alias

Declare Function [имя_функции] GME "[имя_функции]" ([имя_строки] AS String Ptr) AS String Ptr

Public Function [имя_функции] GME "[имя_функции]" ([имя_строки] AS String Ptr) AS String Ptr Export
Но я не могу понять: как вернуть результат, записанный в строку, обратно в программу? Ведь String Ptr указывает на область в памяти, где хранится строка, а чтобы она там хранилась, её надо сначала туда закинуть (ваш К.О.). Вот я и не понимаю, как это сделать.

Заранее благодарен.

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  trew в Ср Апр 18, 2012 7:56 am

Black Doomer пишет:И опять я со своими костылями.
Теперь у меня не получается передать результирующую строку обратно в программу.
Принимаемая переменная и результат у нас определены как String Ptr. Это необходимое условие, так как сторонняя программа для подключения библиотек использует вызовы с использованием типов Double (для чисел) и некий аналог дельфовского PChar для строк.
Стандартное объявление функции, совместимой с вызовами этой программы, выглядит так:
Код:
#define GME cdecl Alias

Declare Function [имя_функции] GME "[имя_функции]" ([имя_строки] AS String Ptr) AS String Ptr

Public Function [имя_функции] GME "[имя_функции]" ([имя_строки] AS String Ptr) AS String Ptr Export
Но я не могу понять: как вернуть результат, записанный в строку, обратно в программу? Ведь String Ptr указывает на область в памяти, где хранится строка, а чтобы она там хранилась, её надо сначала туда закинуть (ваш К.О.). Вот я и не понимаю, как это сделать.

Заранее благодарен.

Привет! Не совсем понял. Это нужно?

Код:

Function GME Alias "GME" (St As String Ptr) AS String Ptr

   Dim As String St1="Hello"
   
   st1=*St + st1' работаем со строкой
   
   Return @St1 ' Возвращаем строку
   
   ' или так
   Return Cast(String Ptr,StrPtr(St1)) ' Возвращаем строку
   
End Function

Если не это, тогда приведи минимальные части:

1) Программы на СИ , а именно функцию, с которой происходит вызов твоей проги
2) Твоей функции.

Хотя вполне возможно, что кто-то поймет лучше меня суть вопроса и ответит раньше.

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Black Doomer в Ср Апр 18, 2012 10:40 am

Поясню.
Возвращаемый указатель указывает на ячейку памяти, где начинается строка.
Я не понимаю, как эту строку закинуть в память, присвоить ей значение и вернуть указатель на неё. А обойтись хочется без всяких функций записи байтов напрямую в память.
Исходник сишной процедуры кинуть не могу, поскольку речь идёт о GameMaker'е, у которого закрытый исходный код.)
Но зато можно поглядеть вот эту статью про написание DLL для него на C++.

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  trew в Ср Апр 18, 2012 12:49 pm

Black Doomer пишет:Поясню.
Возвращаемый указатель указывает на ячейку памяти, где начинается строка.
Я не понимаю, как эту строку закинуть в память, присвоить ей значение и вернуть указатель на неё. А обойтись хочется без всяких функций записи байтов напрямую в память.
Исходник сишной процедуры кинуть не могу, поскольку речь идёт о GameMaker'е, у которого закрытый исходный код.)
Но зато можно поглядеть вот эту статью про написание DLL для него на C++.

Читать , тем более на инглише мне влом, но насколько я понял тебе нужно что-то типа этого:

Код:

Function aa(s As Byte Ptr) As ZString Ptr
   Dim As ZString Ptr ss= Cast(ZString Ptr, s)
   Print *ss
   *ss="Hello world"
   return ss
End Function

Dim s(42) As Byte

For i As Integer = 33 To 74
   s(i-33) = i   
Next
s(42)=0
? *aa(@s(0))
sleep

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

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Black Doomer в Пт Апр 20, 2012 11:26 pm

ВНЕЗАПНО проблема разрешилась. Я забыл выделить Allocate'ом память под передаваемую строку.))
Но всё равно спасибо вам.)

ADD: а теперь я не понимаю, как правильно мне здесь освобождать память. Ведь если не делать этого, то с каждым вызовом этой процедуры она будет засоряться, а в этом ничего хорошего нет. Не подскажете?

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  trew в Сб Апр 21, 2012 8:57 am

Black Doomer пишет:ВНЕЗАПНО проблема разрешилась. Я забыл выделить Allocate'ом память под передаваемую строку.))
Но всё равно спасибо вам.)

ADD: а теперь я не понимаю, как правильно мне здесь освобождать память. Ведь если не делать этого, то с каждым вызовом этой процедуры она будет засоряться, а в этом ничего хорошего нет. Не подскажете?

Так есть же указатель на передаваемую строку, освобождай когда строка не требуется при помощи DeAllocate (Freebasic). Или если выделял память при помощи сишной malloc тогда функцией free.

Можно что-то типа так:

Код:
Function a() As ZString Ptr
   Dim As ZString Ptr Memory = Allocate(10)
   *memory = "Hello"
   Return Memory
End Function
Dim As ZString Ptr g
g = a()
? *g
DeAllocate(g)
Sleep

Или сделай выделение только один раз , а строку статичной для функции:

Код:

Function a() As ZString Ptr
   Static f As Byte
   Static As ZString Ptr Memory
   If f = 0 Then
      Memory = Allocate(100)
      f=1
   EndIf
   *memory = "Hello"
   Return Memory
End Function
Dim As ZString Ptr g
Do
   g = a()
   ? *g
   Sleep(100)
Loop Until MultiKey(1) 'Esc
DeAllocate(g)

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Black Doomer в Сб Апр 21, 2012 1:26 pm

trew, дык это же DLL. =)

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  trew в Сб Апр 21, 2012 2:13 pm

trew, дык это же DLL. =)

И что? Я же показал принцип, а не готовый код. Если DLL вызывается , отрабатывает и выгружается, но прога работает, тогда можно освобождать ресурсы строки, после ее выгрузки. Если DLL работает на протяжении работы всей программы , тогда подойдет пример со статичной переменной. Не пойму что у тебя за затык здесь. Или ты думаешь в DLL нельзя использовать статические переменные?

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Black Doomer в Сб Апр 21, 2012 2:28 pm

trew пишет:
И что? Я же показал принцип, а не готовый код. Если DLL вызывается , отрабатывает и выгружается, но прога работает, тогда можно освобождать ресурсы строки, после ее выгрузки. Если DLL работает на протяжении работы всей программы , тогда подойдет пример со статичной переменной. Не пойму что у тебя за затык здесь. Или ты думаешь в DLL нельзя использовать статические переменные?
Я просто пока что не очень хорошо понимаю, как GM работает с внешними библиотеками.
Пойду пробовать.) Спасибо.

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Black Doomer в Вс Апр 22, 2012 3:57 am

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

Как это сделать?

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  trew в Вс Апр 22, 2012 8:36 am

Ты собираешь DLL из нескольких файлов .bas в один?
Если так , то почитай ЭТУ статью.

Если же у тебя все в одном файле, тогда переменную определяй как Shared

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Black Doomer в Вс Апр 22, 2012 11:53 am

trew пишет:
Если же у тебя все в одном файле, тогда переменную определяй как Shared
Да, у меня всё в одном файле. Но вот с Shared'ом проблемы.
Код:
#define GME cdecl Alias

Declare Function rpl_init GME "rpl_init" () AS Double
Declare Function rpl_test GME "rpl_test" () AS Double

Public Function rpl_init GME "rpl_init" () AS Double
  Dim Shared AS Double Chk=0
  Return 0
End Function

Public Function rpl_test GME "rpl_test" () AS Byte
  Chk = 1
  Return Chk
End Function
Так, увы, не скомпилируется даже.
Мне сдаётся, я где-то здесь напортачил.

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  trew в Вс Апр 22, 2012 12:14 pm

Black Doomer пишет:
trew пишет:
Если же у тебя все в одном файле, тогда переменную определяй как Shared
Да, у меня всё в одном файле. Но вот с Shared'ом проблемы.
Код:
#define GME cdecl Alias

Declare Function rpl_init GME "rpl_init" () AS Double
Declare Function rpl_test GME "rpl_test" () AS Double

Public Function rpl_init GME "rpl_init" () AS Double
  Dim Shared AS Double Chk=0
  Return 0
End Function

Public Function rpl_test GME "rpl_test" () AS Byte
  Chk = 1
  Return Chk
End Function
Так, увы, не скомпилируется даже.
Мне сдаётся, я где-то здесь напортачил.

Объяви эту переменную в начале кода рядом с декларациями функций, но не в функции

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Black Doomer в Вс Апр 22, 2012 12:34 pm

trew пишет:
Объяви эту переменную в начале кода рядом с декларациями функций, но не в функции
Окей, спасибо, работает. А как правильно написать процедуру в DLL, выполняющуюся при закрытии программы (устанавливается в GM), в которой был бы код для освобождения памяти по указателю Result?

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  trew в Вс Апр 22, 2012 1:17 pm

Black Doomer пишет:
trew пишет:
Объяви эту переменную в начале кода рядом с декларациями функций, но не в функции
Окей, спасибо, работает. А как правильно написать процедуру в DLL, выполняющуюся при закрытии программы (устанавливается в GM), в которой был бы код для освобождения памяти по указателю Result?

Я если честно без понятия как там намудрили с подсоединением DLL в GM и узнавать не шибко охота. Но ведь там должна быть возможность вызова любых функций из DLL ?! Кто мешает в DLL сделать дополнительную процедуру (в ней освободить память) и вызвать ее тогда, когда тебе нужно (в данном случае перед завершением программы).

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Black Doomer в Вт Апр 24, 2012 3:38 pm

Ага. Вроде бы всё работает, да на самом деле нет.
Дело вот в чём. При попытке возвращения считанной из файла строки в программу она отображается не полностью, а только какая-либо часть от начала. Причём не всегда одинаковая.
Код:
#define GME cdecl Alias

'Variables
Dim Shared AS ZString Ptr StrResult 'needs there because memory should be released at the end of the program

'rpl_file_read_str (FileIndex AS Double, StrLenght AS Double)
'  Reads string with lenght StrLenght from file with index FileIndex.
'  Returns read string.
Declare Function rpl_file_read_str GME "rpl_file_read_str" (FileIndex AS Double, StrLenght AS Double) AS ZString Ptr

Function rpl_file_read_str GME "rpl_file_read_str" (FileIndex AS Double, StrLenght AS Double) AS ZString Ptr Export
  If StrResult <> 0 Then Deallocate(StrResult): StrResult=0
  StrResult = Allocate(CInt(StrLenght))
  Get #CInt(FileIndex), Seek(FileIndex), *StrResult
  Return StrResult
End Function
Если что, то память, занятая строкой, при закрытии программы очищается - есть специальная процедура, которую я тут не упомянул.

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  trew в Вт Апр 24, 2012 4:25 pm

На первый взгляд кажется все нормально. Но все таки хрень какая-то с декларацией твоей функции.

По сути там оба параметра должны быть целочисленные. Неужели рекомендуется тип Double ? В итоге за счет преобразования из Double в INTEGER может быть потеряна длина строки на один символ , плюс при динамическом выделении надо как минимум прибавлять на единицу для символа "0" . Да и плохо не будет если выделишь памяти чуть побольше (на 5-10)
Кроме того какая там кодировка? Может там не тип Zstring , а Wstring. От этого зависит размер выделяемой памяти.

Я же тебе писал примеры чисто для понимания, но ни в коем случае не конечное решение. А так мне больше сказать нечего из этого обрывка кода. Не попробовав как работает код, что возвращает и т. д. трудно определить причину.


trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Black Doomer в Вт Апр 24, 2012 4:35 pm

trew пишет:По сути там оба параметра должны быть целочисленные. Неужели рекомендуется тип Double ? В итоге за счет преобразования из Double в INTEGER может быть потеряна длина строки на один символ
Он не рекомендуется, он требуется. Без него никак.

Памяти пытался выделить побольше. Толку ноль.
Кодировка там ANSI, а WString Unicode'овый же, разве нет?

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  trew в Вт Апр 24, 2012 5:23 pm

Black Doomer пишет:
trew пишет:По сути там оба параметра должны быть целочисленные. Неужели рекомендуется тип Double ? В итоге за счет преобразования из Double в INTEGER может быть потеряна длина строки на один символ
Он не рекомендуется, он требуется. Без него никак.

Памяти пытался выделить побольше. Толку ноль.
Кодировка там ANSI, а WString Unicode'овый же, разве нет?

Да этот тип юникодовый, почему и спрашивал. Либо выложи минимальный работающий код с визуально-имеющимся багом, или ищи ошибку сам, мне надоело гадать на кофейной гуще.

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Black Doomer в Вс Апр 29, 2012 11:50 am

Вроде бы исправил напиливанием жуткого костыля. Но в связи с тем, что он мне попросту не нравится, у меня есть пара вопросов:
1. Вы можете описать мне различия между String и ZString?
2. Можно ли использовать тип String Ptr при написании кода?

Black Doomer

Сообщения : 27
Дата регистрации : 2011-08-23

Посмотреть профиль http://doom2d.org/forum/viewforum.php?f=19

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  trew в Вс Апр 29, 2012 1:42 pm

Black Doomer пишет:Вроде бы исправил напиливанием жуткого костыля. Но в связи с тем, что он мне попросту не нравится, у меня есть пара вопросов:
1. Вы можете описать мне различия между String и ZString?
2. Можно ли использовать тип String Ptr при написании кода?

1) По ЭТОЙ ссылке в самом низу (Digg GeRR) описан тип String

2) С сишными функциями думаю нет, хотя хз. По крайней мере я не стал бы для разработки своей игры в твоем случае его использовать.

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Возврат указателя на строку производного типа из функции сторонней программе на C

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу

- Похожие темы

 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения