![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Расскажите как объявлять вункции из dll [D7, XP]
KyRo © (2006-12-19 12:32:00)У меня есть dll Подскажите как объявлять функции из нее в своей программе .
Что значат вот эти параметры external,stdcall и.т.д
Иодскажите что бы использовать библиотеку обязательно ли ее регить в виндовс regsvr32 ?
Заранее благодарен.
KyRo (2006-12-22 18:33:00) [1]
> С какого перепугу у тебя String, если у них ByVal ?
Почему несуразицу. Я конечно не знаю бейсика но как я понимаю
> ByVal
Это нечто похожее на Сonst в делфи что бы функция не изменяла значения переменных.
А у них
> As String
> А здесь вроде бы и правильно - твой PChar соответствует
> ихнему ByVal..String - но чем это отличается от 1 ? Почему
> там ты прописал string, а здесь PChar ?
Прописал потому что ты говориш что так правильно ! Потому и поставил посмотреть.
Да при такой дикларации функция работает , но если задекларировать с стрингом то тоже работает !!
Сергей М. (2006-12-22 17:18:00) [2]
> мне интересно тогда из за чего у меня выполняются функции сейчас ?
Не знаю уж что у тебя там "выполняется", но я вижу явную несуразицу.
1.
Ихняя декларация:
Public Declare Function myCoin_setup Lib "MyCommPort.dll" ( ByValmycoin_type As String) As Boolean
Твоя декларация:
function myCoin_setup(Const mycoin_type: String):Boolean; stdcall; external 'MyCommPort.dll';
С какого перепугу у тебя String, если у них ByVal ?
2.
Ихняя декларация:
Public Declare Function myComm_setup Lib "MyCommPort.dll" (ByVal myport_number As Long, ByValmyport_setting As String) As Boolean
Твоя декларация:
function myComm_setup(Const myport_number:LongInt;Const myport_setting:PChar):Boolean; stdcall; external 'MyCommPort.dll';
А здесь вроде бы и правильно - твой PChar соответствует ихнему ByVal..String - но чемэто отличается от 1 ? Почему там ты прописал string, а здесь PChar ?
Нет логики - нет и работоспособности программы.
KyRo (2006-12-22 17:04:00) [3]У меня есть библиотека с которой я работал и в которой находятся функции -она написана на делфи (и исходников к ней у меня нет).
И есть ихняя демонстрационная программа которая написана на бейсике.
К ней у меня есть ее исходники и документация как они работают с библиотекой из бейсика.
В целом проблема в основном заключалась в том что документация действительно очень плохая . В ней как будто забыли упомянуть про процедуры инициализации и окончания работы с библиотекой без которых все работать отказывалось.
> procedure init; stdcall; external 'MyCommPort.dll';
> procedure finish; stdcall; external 'MyCommPort.dll'
Ну и конечно нужно было добавить в декларацию stdcall.
Насчет Pchar то стринг на него в дикларациях я могу поменять , но мне интересно тогда из за чего у меня выполняются функции сейчас ?
Сергей М. (2006-12-22 16:49:00) [4]
> Нет ихние исходники на бейсике
Ты с дуба упал ?)
Сначала ты говоришь что
> сама библиотека написана на делфи
а теперь ты заявляешь иное.
"Как понимать тебя, Саид ?" (С)
KyRo (2006-12-22 16:46:00) [5]
> > var и const я нашол в исходниках ихней программы
>
>
> Покажи, как в ихних дельфийских исходниках выглядят декларации
> экспортируемых функций ...
Нет ихние исходники на бейсике , а вот библиотека на делфи как они декларируют в я писал в прошлом посте.
> Если она писалась искл-но для использования в VB, то там
> должны были быть учтены особенности организации string-переменных
> именно в VB (еще раз - типы Delphi AnsiString и VB String
> несовместимы !)
А почему же у меня все начало работать ? Если я объявил вот так
function myCoin_setup(Const mycoin_type:String):Boolean; stdcall; external 'MyCommPort.dll';
function myComm_setup(Const myport_number:LongInt;Const myport_setting:PChar):Boolean; stdcall; external 'MyCommPort.dll';
function myComm_status(var myport_number:LongInt;var myport_setting:String; var mybuffer_size :LongInt;
var myport_open :Boolean) :Boolean; stdcall; external 'MyCommPort.dll';
function myComm_Open:Boolean; stdcall; external 'MyCommPort.dll';
function myComm_Close:Boolean; stdcall; external 'MyCommPort.dll';
function myComm_poll(var mycoin_number:LongInt;var mycredit_value:LongInt;var mytype_count:String; var myStatus_PooL:Boolean ):Boolean; stdcall; external 'MyCommPort.dll';
procedure init; stdcall; external 'MyCommPort.dll';
procedure finish; stdcall; external 'MyCommPort.dll';
Конечно может я и не прав поменять не сложно , мне просто интересно из за чего тогда функции у меня коректно выполняются ?
Сергей М. (2006-12-22 16:40:00) [6]Кстати, с Variant'ами та же ситуация.
Да и со всеми прочими имеющимися динамическими типами данных.
Имей ввиду.
Сергей М. (2006-12-22 16:13:00) [7]
> var и const я нашол в исходниках ихней программы
Покажи, как в ихних дельфийских исходниках выглядят декларации экспортируемых функций ...
> Бейсик да но как мне сказали библиотека написана была на
> делфи
По барабану на чем она написана.
Если она писалась искл-но для использования в VB, то там должны были быть учтены особенности организации string-переменных именно в VB (еще раз - типы Delphi AnsiString и VB String несовместимы !)
В противном случае (т.е. библиотека задумывалась ими как универсальная, безотносительно сред разработки использующих ее приложений) строковые параметры были бы заданы как PChar. И если так, то соответствующие string-параметры в VB-декларациях обязаныбыть предварены спецификаторами ByVal - при этом в dll передается как раз тот самый указатель на начало строкового буфера, ожидаемый соответственно дельфийским Str: PChar или его Сишным эквивалентом char *strbuf.
ByRef писать не обязательно - по умолчанию все VB-параметры вызовов передаются по ссылке, а не по значению. При этом передача VBшного string-параметра осуществляется как передача адреса внутренней управляющей структурыVB-строковых данных, а не самих строковых данных. Дельфийский же AnsiString тоже содержит внутреннюю упр.структуру, которая не совместима с упр.структурой передаваемой из VB строки, и работать с этой строкой в Делфи-коде обычным образом нельзя.
KyRo (2006-12-22 15:54:00) [8]var и const я нашол в исходниках ихней программы
Public Declare Function myCoin_setup Lib "MyCommPort.dll" (ByVal mycoin_type As String) As Boolean
'Public Declare Function myComm_poll Lib "D:\myWORK\VendingAnalyse\Ps-1\MyCommPort\delphi\MyCommPort.dll" (ByRef mycoin_number As Long, ByRef mycredit_value As Long, ByRef mytype_count As String, ByRef status_poll As String) As Boolean
Public Declare Function myComm_poll Lib "MyCommPort.dll" (ByRef mycoin_number As Long, ByRef mycredit_value As Long, ByRef mytype_count As String, ByRef status_poll As String) As Boolean
Public Declare Function myComm_setup Lib "MyCommPort.dll" (ByVal myport_number As Long, ByVal myport_setting As String) As Boolean
Public Declare Function myComm_status Lib "MyCommPort.dll" (ByRef myport_number As Long, ByRef myport_setting As String, ByRef myBuffer_size As Long, ByRef myport_open As Boolean) As Boolean
Public Declare Function myComm_Close Lib "MyCommPort.dll" () As Boolean
Public Declare Function myComm_Open Lib "MyCommPort.dll" () As Boolean
Public Declare Sub init Lib "MyCommPort.dll" ()
Public Declare Sub finish Lib "MyCommPort.dll" ()
Pchar оказался не совсем не нужным но в некоторых функциях где параметр VAr и возвращается стринг, там с ним функции не хотели работать.
> Васик понятия не имеет ни о каких string'ах, кроме своих
> собственных, а ты пытаешься скормить ему дельфийскую string
> ...
Бейсик да но как мне сказали библиотека написана была на делфи ..
А документация действительно га..но !!
Половины функций и параметров вообще не описаны и если бы не их демонстративные исходники то так и бился бы головой об клавиатуру
Сергей М. (2006-12-22 14:57:00) [9]Хотя нет, вру.
Все правильно - если не указан By Val, соответствующий дельфийский аргумент д.б. объявлен с var.
Но это не касается длинных строк.
Сергей М. (2006-12-22 14:48:00) [10]
> Pchar оказался не нужным.
>
Чего-чего ? Как это "не нужным" ?
Васик понятия не имеет ни о каких string'ах, кроме своих собственных, а ты пытаешься скормить ему дельфийскую string ...
> в некоторых функциях var и const проставить для переменных
что за отсебячина ?
Если бы в Declare Function для некоего параметра фигурировал бы спецификатор ByRef, вот тогда бы var как раз и нужен был.
А const тут вообще ни при чем - поведение компилятора с const и без оного в части сгенерированного кода принципиально ничем не отличается.
KyRo (2006-12-22 14:19:00) [11]Все всем спасибо получилось.
Действительно надо было stdcall поставить и в некоторых функциях var и const проставить для переменных, а Pchar оказался не нужным.
Сергей М. (2006-12-22 12:39:00) [12]Да
KyRo (2006-12-22 11:54:00) [13]
> Кр.того, формальные строковые параметры этих ф-ций следует
> описать не как string, а как PChar
stdcall вроде помогло в первой функции отработало нормально. !
> Тем не менее все используемые тобой ф-ции библ-ки MyCommPort.
> dll, очевидно, должны иметь соглашение stdcall в их соответствующих
> Паскаль-декларациях
То есть объявляюю вункции как
function myCoin_setup(mycoin_type:PChar):Boolean; stdcall; external 'MyCommPort.dll';
А вызываю их так ??
myCoin_setup(PChar(str)):
Сергей М. (2006-12-22 11:30:00) [14]
> KyRo (22.12.06 11:06) [11]
В док-ции фигурирует откровенная чушь насчет классов.
Тем не менее все используемые тобой ф-ции библ-ки MyCommPort.dll, очевидно, должны иметь соглашение stdcall в их соответствующих Паскаль-декларациях.
Кр.того, формальные строковые параметры этих ф-ций следует описать не как string, а как PChar
> компилятор мне выдает ошибку
> exception class EConvertError
Компилятор не может выдать такой ошибки, это ошибка времени выполнения, а не времени компиляции.
KyRo (2006-12-22 11:19:00) [15]
> что за бред? Либо класс с методами, либо набор функций.
> Определитесь уже, процедурный у вас подход или все же объектно-
> ориентированный...
Это цитата из документации !! Библиотека по словам поставщика написана на делфе . В ихнем тестовом примере который они постовляют они объявляют функции как обычные функции это вижуал бейсик
Option Explicit
Public Declare Function myCoin_setup Lib "MyCommPort.dll" (ByVal mycoin_type As String) As Boolean
'Public Declare Function myComm_poll Lib "D:\myWORK\VendingAnalyse\Ps-1\MyCommPort\delphi\MyCommPort.dll" (ByRef mycoin_number As Long, ByRef mycredit_value As Long, ByRef mytype_count As String, ByRef status_poll As String) As Boolean
Public Declare Function myComm_poll Lib "MyCommPort.dll" (ByRef mycoin_number As Long, ByRef mycredit_value As Long, ByRef mytype_count As String, ByRef status_poll As String) As Boolean
Public Declare Function myComm_setup Lib "MyCommPort.dll" (ByVal myport_number As Long, ByVal myport_setting As String) As Boolean
Public Declare Function myComm_status Lib "MyCommPort.dll" (ByRef myport_number As Long, ByRef myport_setting As String, ByRef myBuffer_size As Long, ByRef myport_open As Boolean) As Boolean
Public Declare Function myComm_Close Lib "MyCommPort.dll" () As Boolean
Public Declare Function myComm_Open Lib "MyCommPort.dll" () As Boolean
Public Declare Sub init Lib "MyCommPort.dll" ()
Public Declare Sub finish Lib "MyCommPort.dll" ()
clickmaker (2006-12-22 11:13:00) [16]
> DLL библиотека реализована в виде класса (class) в составе
> функций.
что за бред? Либо класс с методами, либо набор функций. Определитесь уже, процедурный у вас подход или все же объектно-ориентированный...
подозрение вызывает также параметр типа String. Что это за стринг? В разных языках такой тип реализован по-разному.
Для универсальных ДЛЛ обычно используют PChar (char*), а для CОМ-серверов BSTR (портируется в дельфи как WideString)
KyRo (2006-12-22 11:06:00) [17]И так у меня что то так не чего и не получается посмотрите может что то подскажете как выйти из положения.
По описанию библиотечных функций
Обязательно ! Перед использованием библиотеки MyCommPort.dll и исполняемого модуля PS2Comm.exe примера программы необходимо проверить наличие файлов с расширениями DLL и OCX из папки Support поставляемого ПО в системной директории WINDOWS и в случае их отсутствия разместить их там и зарегистрировать в системном реестре (см. ниже).
3.2. Состав.
DLL библиотека реализована в виде класса (class) в составе функций.
myCoin_setup(mycoin_type As String) As Boolean
myComm_setup(myport_number As Long, myport_setting As String) As Boolean
myComm_status(myport_number As Long, myport_setting As String, mybuffer_size As Long, myport_open As Boolean) As Boolean
PSCOMM_Open()As Boolean
PSCOMM_Close()As Boolean
myComm_poll(mycoin_number As Long, mycredit_value As Long, mytype_count As String) As Boolean
3.3. Функции.
myCoin_setup(mycoin_type As String). Функция устанавливает стоимость 6 каналов (монет, купюр) платежной системы. Тип функции – логическая переменная. Параметр – строковая переменная в виде перечисленных через запятую значений стоимости соответствующих каналов. По умолчанию ПО использует значение переменной, равное “5,10,25,50,100,0” и соответствующее стоимости каналов соответственно как 5, 10, 25, 50, 100 и 0.
И так я все функции объявляю вот так
type
TPs1 = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
// а из программы ее можно вызывать так:
function myCoin_setup(mycoin_type:String):Boolean; external 'MyCommPort.dll';
function myComm_setup(myport_number:LongInt;myport_setting:String):Boolean; external 'MyCommPort.dll';
function myComm_status(myport_number:LongInt; myport_setting:String; mybuffer_size :LongInt;
myport_open :Boolean) :Boolean; external 'MyCommPort.dll';
function myComm_Open:Boolean; external 'MyCommPort.dll';
function myComm_Close:Boolean; external 'MyCommPort.dll';
function myComm_poll(mycoin_number:LongInt;mycredit_value:LongInt;mytype_count:String):Bo olean; external 'MyCommPort.dll';
var
Ps1: TPs1;
После чего по документации надо сначала вызвать функцию настройки номиналов каналов , а потом функцию настройки ком порта.
Так вот когда я вызываю эту функцию
bool:= myCoin_setup(s);
где S = '5,10,25,50,100,0' как показано в документации то
компилятор мне выдает ошибку
exception class EConvertError with message "hщ(Квадратик не знаю как написать)' is not a valid integer value
Судя по ошибке я понимаю что функция дробит строку и переводит значение в интеджер и но меня смущает в ошибке вот эта смешеная русско английская строчка. Может оно берет и перекодирует в какую то кодировку которой у меня нет на компьютере ????
В тестовом примере на вижуал бейсике выглядит вот так
объявляют функцию
Public Declare Function myCoin_setup Lib "MyCommPort.dll" (ByVal mycoin_type As String) As Boolean
вот так пытаются ее выполнить.
Success = myCoin_setup(ps_info.coin_type(0) & "," & ps_info.coin_type(1) & "," & ps_info.coin_type(2) & "," & ps_info.coin_type(3) & "," & ps_info.coin_type(4) & "," & ps_info.coin_type(5))
Подскажите может кто знает ?
Anatoly Podgoretsky (2006-12-19 13:59:00) [18]> Сергей М. (19.12.2006 13:12:08) [8]
По барабану если честная, но это видимо тот случай.
clickmaker (2006-12-19 13:33:00) [19]
> Эту библиотеку по документации надо регить. Я ее зарегил
> .
а зачем регить библиотеку, если потом просто вызывать ее функции? Обычно, если регишь COM-сервер, то потом вызываешь СoCreateInstance с соотв. гуидом и вызываешь методы созданного объекта
Сергей М. (2006-12-19 13:12:00) [20]
> там документация под Вижуал бейсик
Так это ж расчудесно !)
Портировать VB-код в Делфи-код проще простого, гораздо легче чем С/СPP-код. Приводи примеры - посмотрим что там и как происходит..
И по барабану начем написана сама библиотека.