PureBasic - форум

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

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


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Возвращаемые значения чисел из DLL


Возвращаемые значения чисел из DLL

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

1

Вот, пример изучаю.
Создал по примеру библиотеку test_dll.dll, скомпилировал.
Код dll:

Код:
ProcedureDLL Plus(a, b)
  ProcedureReturn a+b
EndProcedure


ProcedureDLL Msg_Box(Title.s, Message.s)
  MessageRequester(Title, Message)
EndProcedure

Создал по примеру программку load_dll.exe
Код exe:

Код:
If OpenLibrary(1, "test_dll.dll")=0 ; Открываем динамическую библиотеку подпрограмм 
  MessageRequester("", "Отсутствует файл MyDLL.dll")
  End ; Завершение работы программы
EndIf

a.f=10.56 ; Запись данных в переменные
b.f=20.77
Debug a
Debug b
Result.f=CallCFunction(1, "Plus", a, b) ; Вызов функции Plus
String.s="a+b="+Str(Result)
Debug Result
CallCFunction(1, "Msg_Box", @"Сообщение", @String)  ; Вызов функции Message

CloseLibrary(1) ; Закрытие динамической библиотеки подпр

В этой программке попробовал переменным a, b присвоить числа с плавающей точкой, т.е. суффикс .f приписал.
Однако в Debug переменная Result = 32.0, a = 10.56***********, b = 20.77************
В MessageRecuster - е - просто 32
Как получить Result = 31.33 ?

0

2

Нужно было и в самой DLLке указать что в переменных будут числа с плавающей точкой.
Процедура Plus, должна иметь такой вид.

Код:
ProcedureDLL.f Plus(a.f, b.f)
  ProcedureReturn a+b
EndProcedure

0

3

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

Нужно было и в самой DLLке указать что в переменных будут числа с плавающей точкой.Процедура Plus, должна иметь такой вид.

Я хотел отписать именно так Юрию, но когда попробовал, у меня почему при такой записи возвращаемое значение "0"  o.O 
В процедуре, находящейся в коде, такой код работает правильно, а если в DLL, хрень какая то.

0

4

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

меня почему при такой записи возвращаемое значение "0"

У меня возвращает 6-ти значное число.
Эксперимент показал что проблема не в DLLке, а в функции CallFunction.
В справке написанно, что функция CallFunction возвращает только целые числа.
Есть два способа решения проблемы.
Можно использовать прототип функции Plus.

Код:
If OpenLibrary(1, "test_dll.dll")=0 ; Открываем динамическую библиотеку подпрограмм 
  MessageRequester("", "Отсутствует файл MyDLL.dll")
  End ; Завершение работы программы
EndIf

Prototype.f ProtoPlus(a.f, b.f)
Plus.ProtoPlus = GetFunction(1, "Plus")

a.f=10.56 ; Запись данных в переменные
b.f=20.77

Debug a
Debug b
Result.f=Plus(a, b) ; Вызов функции Plus
String.s="a+b="+StrF(Result)
Debug Result
CallFunction(1, "Msg_Box", @"Сообщение", @String)  ; Вызов функции Message

CloseLibrary(1) ; Закрытие динамической библиотеки подпр

Но можно результат передавать через указатель.

DLL

Код:
ProcedureDLL Plus(a.f, b.f, *Point)
  PokeF(*Point, a+b)
EndProcedure

ProcedureDLL Msg_Box(Title.s, Message.s)
  MessageRequester(Title, Message)
EndProcedure

EXE

Код:
If OpenLibrary(1, "test_dll.dll")=0 ; Открываем динамическую библиотеку подпрограмм 
  MessageRequester("", "Отсутствует файл MyDLL.dll")
  End ; Завершение работы программы
EndIf

a.f=10.56 ; Запись данных в переменные
b.f=20.77
Result.f=0
Debug a
Debug b
CallFunction(1, "Plus", a, b, @Result) ; Вызов функции Plus
String.s="a+b="+StrF(Result)
Debug Result
CallFunction(1, "Msg_Box", @"Сообщение", @String)  ; Вызов функции Message

CloseLibrary(1) ; Закрытие динамической библиотеки подпр

0

5

Вот при такой записи возвращает ноль:

Код:
ProcedureDLL.f Plus(a.f, b.f)
  ProcedureReturn a+b
EndProcedure

А при такой да как ты и сказал шестизначное число:

Код:
ProcedureDLL Plus(a.f, b.f)
  ProcedureReturn a+b
EndProcedure

Не в обиду Петру и Юрию: эту тему неплохо бы назвать Возвращаемые значения чисел из DLL. На мой взгляд так название темы  информативнее отображает ее суть. В будующем легче будет найти ответ на данный вопрос кому бы то ни было.  :yep:

Отредактировано haav (03.04.2010 15:40:41)

0

6

Что-то я в полнейший ступор вошел.
Видать я - совсем дерево :)
Все вышеприведенные примеры ( и для DLL и для EXE) испробовал.
Однако String = 0 или 0.0 или 0.000000
Вот последний кодинг:
DLL код:

Код:
ProcedureDLL.f Plus(a.f, b.f)
  ProcedureReturn a+b
EndProcedure

ProcedureDLL Msg_Box(Title.s, Message.s)
  MessageRequester(Title, Message)
EndProcedure

Код проги:

Код:
If OpenLibrary(1, "test_dll.dll")=0 ; Открываем динамическую библиотеку подпрограмм 
  MessageRequester("", "Отсутствует файл MyDLL.dll")
  End ; Завершение работы программы
EndIf

a.f=10.56 ; Запись данных в переменные
b.f=20.77
Debug a
Debug b
Result=CallCFunction(1, "Plus", a, b) ; Вызов функции Plus
String.s="a+b="+Str(Result)
Debug Result
CallCFunction(1, "Msg_Box", @"Сообщение", @String)  ; Вызов функции Message

CloseLibrary(1) ; Закрытие динамической библиотеки подпр

Результат отладки:
10.5600004196167
20.77000045776367
268439728 (Result) - это как?

Отредактировано Юрий (03.04.2010 23:01:12)

0

7

В 4 посте Петр написал как надо.  Даже подписал где EXE где DLL

0

8

Из 4-го поста сделал код так:
Dll:

Код:
ProcedureDLL Plus(a.f, b.f, *Point)
  PokeF(*Point, a+b)
EndProcedure

ProcedureDLL Msg_Box(Title.s, Message.s)
  MessageRequester(Title, Message)
EndProcedure


EXE:

Код:
If OpenLibrary(1, "test_dll.dll")=0 ; Открываем динамическую библиотеку подпрограмм 
  MessageRequester("", "Отсутствует файл MyDLL.dll")
  End ; Завершение работы программы
EndIf

a.f=10.56 ; Запись данных в переменные
b.f=20.77
Result.f=0
Debug a
Debug b
CallFunction(1, "Plus", a, b, @Result) ; Вызов функции Plus
String.s="a+b="+StrF(Result)
Debug Result
CallFunction(1, "Msg_Box", @"Сообщение", @String)  ; Вызов функции Message

CloseLibrary(1) ; Закрытие динамической библиотеки подпр

Debug =
10.5600004196167
20.77000045776367
0.0 - (это  Result)
А MessageRequester = 0.000000

0

9

В версии PB 4.40 действительно такая ерунда.
В 4.31 всё ОК.

Но вариант с прототипом работает.

DLL

Код:
ProcedureDLL.f Plus(a.f, b.f)
  ProcedureReturn a+b
EndProcedure

ProcedureDLL Msg_Box(Title.s, Message.s)
  MessageRequester(Title, Message)
EndProcedure

EXE

Код:
If OpenLibrary(1, "test_dll.dll")=0 ; Открываем динамическую библиотеку подпрограмм 
  MessageRequester("", "Отсутствует файл MyDLL.dll")
  End ; Завершение работы программы
EndIf

Prototype.f ProtoPlus(a.f, b.f)
Plus.ProtoPlus = GetFunction(1, "Plus")

a.f=10.56 ; Запись данных в переменные
b.f=20.77

Debug a
Debug b
Result.f=Plus(a, b) ; Вызов функции Plus
String.s="a+b="+StrF(Result)
Debug Result
CallFunction(1, "Msg_Box", @"Сообщение", @String)  ; Вызов функции Message

CloseLibrary(1) ; Закрытие динамической библиотеки подпр

0

10

Да, действительно, теперь работает. У меня 4.40 установлена.
Теперь в вопросах обязательно буду указывать версию PB.
А как вот сделать, чтобы Result = 31.33, а не 31.330002 в MessageRequester?

0

11

Юрий написал(а):

А как вот сделать, чтобы Result = 31.33, а не 31.330002 в MessageRequester?

Должно быть так в коде

Код:
String.s="a+b="+StrF(Result, 2)

0

12

Спасибо, Петр и haav.
Возможно изучение программирования  на PB я не с того начал (это я про dll).
Но все равно очень интересно, познавательно. Кстати это моя первая dll была.
Эту dll мне удалось использовать (открыть, вызвать ф-ю) из др. языков/сред программирования.
А Debug в PB - это вещь!

0

13

Юрий написал(а):

Эту dll мне удалось использовать (открыть, вызвать ф-ю) из др. языков/сред программирования.

Я бы удивился, если бы не получилось.
Ведь создаётся стандартная DLLка, которую теоритически можно вызвать из любой среды программирования.

Кроме стандартных DLLок, можно создавать DLLки, формата CDecl.

0

14

Юрий написал(а):

А Debug в PB - это вещь!

Можно сделать и по другому.
Поставить точку остановки на интерсующую строку (кнопка F9) и когда программа будет остановленна, просто навести курсор мышки на интерисующую переменную.
В итоге, появится всплывающее окошко с текущим значением переменной.

http://s005.radikal.ru/i210/1004/04/991f6c6ca328.png

Ещё можно в меню "Отладчик" выбрать пункт "Просмотр переменных" и посмотреть что хранится во всех переменных, массивах, структурах, динамических списках программы.

http://i029.radikal.ru/1004/48/6fd45b4e114c.png

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Возвращаемые значения чисел из DLL