Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 16.12.2017, 20:34
Olstgel Olstgel вне форума
Прохожий
 
Регистрация: 16.12.2017
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Помогите подключить библиотеку dll

Существует приложение типа системы без GUI, в состав которой входят уже несколько прикладных программ, работающих на общих библиотеках dll. Так же в комплекте идёт пакет для разработки, включающий в себя хедеры для Си и файлы сценариев .vb для Бейсик.
Как я понимаю, на основе этой информации, можно при правильном синтаксисе использовать эти функции?

Последний раз редактировалось Olstgel, 27.01.2018 в 23:35.
Ответить с цитированием
  #2  
Старый 17.12.2017, 00:59
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

ПОнимаешь правильно. просто надо написать правильный импорт функций. Например, как-то так:
Код:
function __apiCheckVersion(versionCompatibility : Integer; versionInfo : PChar) : Boolean; extern 'dllname.dll';
Ответить с цитированием
  #3  
Старый 17.12.2017, 21:08
Olstgel Olstgel вне форума
Прохожий
 
Регистрация: 16.12.2017
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Ну да, вроде так и применяю. Но вот беда - в исходном хедере функция инициализации сервера описана так:
'С#
Код:
 FAR PASCAL Init(unsigned int far *handle);



Мой "сервер" запускается и инициализируется (могу видеть эти процессы), но от своей программы в этот момент получаю краш "Debugger fault notification: access violation at addr=..., write of addr=... . Process stoped".

Последний раз редактировалось Olstgel, 27.01.2018 в 23:37.
Ответить с цитированием
  #4  
Старый 18.12.2017, 04:53
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну дык правильно крашится, у тебя функция неправильно описана. Должно быть как-то так:
Код:
function __apiInit(var Handle : Cardinal) : Boolean; stdcall; external 'Api32.dll';
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Olstgel (18.12.2017)
  #5  
Старый 18.12.2017, 10:22
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

только не boolean, а BOOL
Ответить с цитированием
Этот пользователь сказал Спасибо icWasya за это полезное сообщение:
Olstgel (18.12.2017)
  #6  
Старый 18.12.2017, 15:02
Olstgel Olstgel вне форума
Прохожий
 
Регистрация: 16.12.2017
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Спасибо! С моим-то опытом даже в голову не пришла мысль.

Последний раз редактировалось Olstgel, 18.12.2017 в 15:15.
Ответить с цитированием
  #7  
Старый 30.12.2017, 13:37
Olstgel Olstgel вне форума
Прохожий
 
Регистрация: 16.12.2017
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Вот такой вопрос ещё:
Функция должна передавать версию сервера (5 символов).

Код:
implementation

 Function BVersion (comp: longint; vtxt: shortstring; var vlen: integer) : integer; stdcall; external '2.dll';
//------------

  Function Version( var comp : longint; var vInf : string) : integer;
    var
      tmp : shortString;
      n : Integer;
  begin
    result := BVersion(Comp, tmp, n);
    If n > 0 Then
      begin
        vInf := ansimidstr(tmp,0, n);   //ansileftstr(tmp, n);
      end;
end;
В итоге переменная "n" несёт в себе значение =5 ,
а переменная "tmp" приносит только '.1.3'#0#0#0.....
По какой причине пропущен первый символ? Эта же функция в бейсике возвращает '6.1.3'.

Последний раз редактировалось Olstgel, 27.01.2018 в 23:38.
Ответить с цитированием
  #8  
Старый 30.12.2017, 21:15
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Потому что shortstring не совсем тот тип, который надо использовать. передай туда массив [0..255] of char или что-то подобное. Потом его можно через pchar перевести в нормальную строку.

ЗЫ. В shortstring первый байт занят под длинну строки, вот ты и получаешь что-то неправильное.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
Olstgel (31.12.2017)
  #9  
Старый 31.12.2017, 02:34
Olstgel Olstgel вне форума
Прохожий
 
Регистрация: 16.12.2017
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Да, ключевым решением оказалось объявление tmp [0..255] as char и vtxt как Pchar. Изначально пробовал, но vtxt ума не хватило сразу переопределить.
Странно почему в таблице соответствия типов VB/С/Delphi об этом ни слова. Может не так ищу или читаю. Главное - что с вашими подсказками всё начинает сразу работать. ))
Спасибо!!
Ответить с цитированием
  #10  
Старый 31.12.2017, 12:33
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Дело в том, что для паскалевских строк (shortstring) вообще нет аналогов в других языках. Так что по определению надо использовать аналоги PChar или что-то с ним совместимое. Т.е. можно было сразу выделить память под PChar и его передавать в функцию.
Ответить с цитированием
  #11  
Старый 03.01.2018, 00:34
Olstgel Olstgel вне форума
Прохожий
 
Регистрация: 16.12.2017
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

И снова у меня затык.
И опять по старым чертежам: пробую в Бейсике - всё работает, перекладываю в Делфи - отваливается.
Опишу проблему комментариями в кодах
'VB
Код:
Private Declare Function VBstart Lib "vb.dll" (scope&) As Integer
Private Declare Sub VBstep Lib "vb.dll" (ByVal scope&, ByVal modl$, ByVal step$, ByVal Pars$, ByVal pars2$)


Function Fstart() As Integer       
    Fstart = VBstart(dllscope)
End Function

Sub Fstep(ByVal modl$, ByVal step$, ByVal Pars$, ByVal pars2$)

    If Len(modl) = 0 Then
        modl = ""         
    End If
    If Len(step) = 0 Then
        step = ""         
    End If
    If Len(Pars) = 0 Then
        pars = ""        
    End If
    If Len(pars2) = 0 Then
        pars2 = ""      
    End If
    Call VBstep(dllscope, modl, step, pars, pars2)
   
End Sub

Private Sub Step_Button_Click()
 
  modl = "Test"  
  step = "Data"  
  Call Fstart
  Call Fstep(modl, step, Pars, pars2)
 
 End Sub

'Pas
Код:
Function Fstart() :integer;
Procedure Fstep(modl : string; step : string; pars : string; pars2 : string);

 implementation

  Function VBstart(var scope: longint) : integer; stdcall; external 'vb.dll';
  Procedure VBstep (var scope: LongInt; modl: string; step: string; pars: string; pars2: string); stdcall; external 'vb.dll';

// функ. запуска сервера. 
function Fstart() :integer;
    begin
      result:= VBstart(dllscope);
    end;
 
// проц. загрузки файла на сервер
 Procedure Fstep(modl : string; step : string; pars : string; pars2 : String);

begin
    If Length(modl) = 0 Then 
    begin
        modl := '';     
    End;
    If Length(step) = 0 Then
    begin
        step := '';       
    End;
    If Length(pars) = 0 Then
    begin
        pars := '';       
    End;
    If Length(pars2) = 0 Then
   begin
      pars2 := '';     
    End;
    
    VBstep(dllscope, modl, step, pars, pars2);
end;
 
 procedure TForm1.Step_Click(Sender: TObject);
begin
  modl:='Test';  // передаём заведомо известные значения в переменные
 step:='Data';
 Fstart();       // инициализируем сервер

Fstep(modl, step, pars, pars2); // отправляем Fstep('Test', 'Data','', '')
// ...
// в этом месте находится следующая функция (независимая от состояния сервера), 
//которая выдаёт сообщение об ошибке в случае неуспешной
// операции. 
end;
 
Создалось впечатление, что отправляю то ли не то, то ли не туда. Пробовал подсовывать разные типы, но ответ всегда одинаков.
Даже если я буду передавать Fstep('', '','', '') в таком виде, то по условию сервера мне должен прийти ответ "FILE NOT FOUND" (моделировал ситуацию в Бейсике), а пока что постоянно вижу только "ACCESS DENIED" как в случае, если сервер не инициализирован. Хотя после функции Fstep я продолжаю видеть сервер в состоянии "Ready"
Использую Delphi7 , Win_XP_32x.

Последний раз редактировалось Olstgel, 03.01.2018 в 00:39.
Ответить с цитированием
  #12  
Старый 03.01.2018, 05:26
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

1. Тебе уже сказали, что String не годится для функции из DLL.
2. ACCESS DENIED это возврат из функции или эксепшн?
Ответить с цитированием
  #13  
Старый 03.01.2018, 17:37
Olstgel Olstgel вне форума
Прохожий
 
Регистрация: 16.12.2017
Сообщения: 9
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
1. Тебе уже сказали, что String не годится для функции из DLL.
2. ACCESS DENIED это возврат из функции или эксепшн?

Передавал и как Pchar - итог одинаков. Кстати некоторые функции у меня всё же работают с типом String.
ACCESS DENIED это возврат из функции(внутрисерверный обработчик ошибок).
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:28.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter