Возврат указателя на строку производного типа из функции сторонней программе на C
Участников: 2
FreeBasic :: Программирование :: Общее
Страница 1 из 1
Возврат указателя на строку производного типа из функции сторонней программе на C
И опять я со своими костылями.
Теперь у меня не получается передать результирующую строку обратно в программу.
Принимаемая переменная и результат у нас определены как String Ptr. Это необходимое условие, так как сторонняя программа для подключения библиотек использует вызовы с использованием типов Double (для чисел) и некий аналог дельфовского PChar для строк.
Стандартное объявление функции, совместимой с вызовами этой программы, выглядит так:
Заранее благодарен.
Теперь у меня не получается передать результирующую строку обратно в программу.
Принимаемая переменная и результат у нас определены как 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
Заранее благодарен.
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Black Doomer пишет:И опять я со своими костылями.
Теперь у меня не получается передать результирующую строку обратно в программу.
Принимаемая переменная и результат у нас определены как String Ptr. Это необходимое условие, так как сторонняя программа для подключения библиотек использует вызовы с использованием типов Double (для чисел) и некий аналог дельфовского PChar для строк.
Стандартное объявление функции, совместимой с вызовами этой программы, выглядит так:Но я не могу понять: как вернуть результат, записанный в строку, обратно в программу? Ведь String Ptr указывает на область в памяти, где хранится строка, а чтобы она там хранилась, её надо сначала туда закинуть (ваш К.О.). Вот я и не понимаю, как это сделать.
- Код:
#define GME cdecl Alias
Declare Function [имя_функции] GME "[имя_функции]" ([имя_строки] AS String Ptr) AS String Ptr
Public Function [имя_функции] GME "[имя_функции]" ([имя_строки] AS String Ptr) AS String Ptr Export
Заранее благодарен.
Привет! Не совсем понял. Это нужно?
- Код:
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
Поясню.
Возвращаемый указатель указывает на ячейку памяти, где начинается строка.
Я не понимаю, как эту строку закинуть в память, присвоить ей значение и вернуть указатель на неё. А обойтись хочется без всяких функций записи байтов напрямую в память.
Исходник сишной процедуры кинуть не могу, поскольку речь идёт о GameMaker'е, у которого закрытый исходный код.)
Но зато можно поглядеть вот эту статью про написание DLL для него на C++.
Возвращаемый указатель указывает на ячейку памяти, где начинается строка.
Я не понимаю, как эту строку закинуть в память, присвоить ей значение и вернуть указатель на неё. А обойтись хочется без всяких функций записи байтов напрямую в память.
Исходник сишной процедуры кинуть не могу, поскольку речь идёт о GameMaker'е, у которого закрытый исходный код.)
Но зато можно поглядеть вот эту статью про написание DLL для него на C++.
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
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
ВНЕЗАПНО проблема разрешилась. Я забыл выделить Allocate'ом память под передаваемую строку.))
Но всё равно спасибо вам.)
ADD: а теперь я не понимаю, как правильно мне здесь освобождать память. Ведь если не делать этого, то с каждым вызовом этой процедуры она будет засоряться, а в этом ничего хорошего нет. Не подскажете?
Но всё равно спасибо вам.)
ADD: а теперь я не понимаю, как правильно мне здесь освобождать память. Ведь если не делать этого, то с каждым вызовом этой процедуры она будет засоряться, а в этом ничего хорошего нет. Не подскажете?
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
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
trew, дык это же DLL. =)
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
trew, дык это же DLL. =)
И что? Я же показал принцип, а не готовый код. Если DLL вызывается , отрабатывает и выгружается, но прога работает, тогда можно освобождать ресурсы строки, после ее выгрузки. Если DLL работает на протяжении работы всей программы , тогда подойдет пример со статичной переменной. Не пойму что у тебя за затык здесь. Или ты думаешь в DLL нельзя использовать статические переменные?
trew- Сообщения : 331
Дата регистрации : 2010-10-14
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Я просто пока что не очень хорошо понимаю, как GM работает с внешними библиотеками.trew пишет:
И что? Я же показал принцип, а не готовый код. Если DLL вызывается , отрабатывает и выгружается, но прога работает, тогда можно освобождать ресурсы строки, после ее выгрузки. Если DLL работает на протяжении работы всей программы , тогда подойдет пример со статичной переменной. Не пойму что у тебя за затык здесь. Или ты думаешь в DLL нельзя использовать статические переменные?
Пойду пробовать.) Спасибо.
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Так, все проблемы решены, кроме одной.
Как сделать в DLL переменную глобальной для всех модулей?
Например, я объявляю в одной функции указатель на ZString и выделяю ему немного памяти. Потом мне необходимо уже из другой функции получить доступ к этому указателю и освободить память по нему.
Как это сделать?
Как сделать в DLL переменную глобальной для всех модулей?
Например, я объявляю в одной функции указатель на ZString и выделяю ему немного памяти. Потом мне необходимо уже из другой функции получить доступ к этому указателю и освободить память по нему.
Как это сделать?
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Ты собираешь DLL из нескольких файлов .bas в один?
Если так , то почитай ЭТУ статью.
Если же у тебя все в одном файле, тогда переменную определяй как Shared
Если так , то почитай ЭТУ статью.
Если же у тебя все в одном файле, тогда переменную определяй как Shared
trew- Сообщения : 331
Дата регистрации : 2010-10-14
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Да, у меня всё в одном файле. Но вот с Shared'ом проблемы.trew пишет:
Если же у тебя все в одном файле, тогда переменную определяй как 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
Мне сдаётся, я где-то здесь напортачил.
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Black Doomer пишет:Да, у меня всё в одном файле. Но вот с Shared'ом проблемы.trew пишет:
Если же у тебя все в одном файле, тогда переменную определяй как 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
Окей, спасибо, работает. А как правильно написать процедуру в DLL, выполняющуюся при закрытии программы (устанавливается в GM), в которой был бы код для освобождения памяти по указателю Result?trew пишет:
Объяви эту переменную в начале кода рядом с декларациями функций, но не в функции
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Black Doomer пишет:Окей, спасибо, работает. А как правильно написать процедуру в DLL, выполняющуюся при закрытии программы (устанавливается в GM), в которой был бы код для освобождения памяти по указателю Result?trew пишет:
Объяви эту переменную в начале кода рядом с декларациями функций, но не в функции
Я если честно без понятия как там намудрили с подсоединением DLL в GM и узнавать не шибко охота. Но ведь там должна быть возможность вызова любых функций из DLL ?! Кто мешает в DLL сделать дополнительную процедуру (в ней освободить память) и вызвать ее тогда, когда тебе нужно (в данном случае перед завершением программы).
trew- Сообщения : 331
Дата регистрации : 2010-10-14
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Ага. Вроде бы всё работает, да на самом деле нет.
Дело вот в чём. При попытке возвращения считанной из файла строки в программу она отображается не полностью, а только какая-либо часть от начала. Причём не всегда одинаковая.
Дело вот в чём. При попытке возвращения считанной из файла строки в программу она отображается не полностью, а только какая-либо часть от начала. Причём не всегда одинаковая.
- Код:
#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
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
На первый взгляд кажется все нормально. Но все таки хрень какая-то с декларацией твоей функции.
По сути там оба параметра должны быть целочисленные. Неужели рекомендуется тип Double ? В итоге за счет преобразования из Double в INTEGER может быть потеряна длина строки на один символ , плюс при динамическом выделении надо как минимум прибавлять на единицу для символа "0" . Да и плохо не будет если выделишь памяти чуть побольше (на 5-10)
Кроме того какая там кодировка? Может там не тип Zstring , а Wstring. От этого зависит размер выделяемой памяти.
Я же тебе писал примеры чисто для понимания, но ни в коем случае не конечное решение. А так мне больше сказать нечего из этого обрывка кода. Не попробовав как работает код, что возвращает и т. д. трудно определить причину.
По сути там оба параметра должны быть целочисленные. Неужели рекомендуется тип Double ? В итоге за счет преобразования из Double в INTEGER может быть потеряна длина строки на один символ , плюс при динамическом выделении надо как минимум прибавлять на единицу для символа "0" . Да и плохо не будет если выделишь памяти чуть побольше (на 5-10)
Кроме того какая там кодировка? Может там не тип Zstring , а Wstring. От этого зависит размер выделяемой памяти.
Я же тебе писал примеры чисто для понимания, но ни в коем случае не конечное решение. А так мне больше сказать нечего из этого обрывка кода. Не попробовав как работает код, что возвращает и т. д. трудно определить причину.
trew- Сообщения : 331
Дата регистрации : 2010-10-14
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Он не рекомендуется, он требуется. Без него никак.trew пишет:По сути там оба параметра должны быть целочисленные. Неужели рекомендуется тип Double ? В итоге за счет преобразования из Double в INTEGER может быть потеряна длина строки на один символ
Памяти пытался выделить побольше. Толку ноль.
Кодировка там ANSI, а WString Unicode'овый же, разве нет?
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Black Doomer пишет:Он не рекомендуется, он требуется. Без него никак.trew пишет:По сути там оба параметра должны быть целочисленные. Неужели рекомендуется тип Double ? В итоге за счет преобразования из Double в INTEGER может быть потеряна длина строки на один символ
Памяти пытался выделить побольше. Толку ноль.
Кодировка там ANSI, а WString Unicode'овый же, разве нет?
Да этот тип юникодовый, почему и спрашивал. Либо выложи минимальный работающий код с визуально-имеющимся багом, или ищи ошибку сам, мне надоело гадать на кофейной гуще.
trew- Сообщения : 331
Дата регистрации : 2010-10-14
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Вроде бы исправил напиливанием жуткого костыля. Но в связи с тем, что он мне попросту не нравится, у меня есть пара вопросов:
1. Вы можете описать мне различия между String и ZString?
2. Можно ли использовать тип String Ptr при написании кода?
1. Вы можете описать мне различия между String и ZString?
2. Можно ли использовать тип String Ptr при написании кода?
Re: Возврат указателя на строку производного типа из функции сторонней программе на C
Black Doomer пишет:Вроде бы исправил напиливанием жуткого костыля. Но в связи с тем, что он мне попросту не нравится, у меня есть пара вопросов:
1. Вы можете описать мне различия между String и ZString?
2. Можно ли использовать тип String Ptr при написании кода?
1) По ЭТОЙ ссылке в самом низу (Digg GeRR) описан тип String
2) С сишными функциями думаю нет, хотя хз. По крайней мере я не стал бы для разработки своей игры в твоем случае его использовать.
trew- Сообщения : 331
Дата регистрации : 2010-10-14
FreeBasic :: Программирование :: Общее
Страница 1 из 1
Права доступа к этому форуму:
Вы не можете отвечать на сообщения
|
|