Проблема с dll

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Проблема с dll

Сообщение ajunta » 23.11.2007 23:22:32

Всем привет, при попытке работать с dll сталкиваюсь со следующей проблемой, возникает при попытке запустить программу из IDE, пишет, что собрано нормально:

Debugger Error:
Ooops the debugger entered the the error state, save your work now!
Hit Stop, and hope the best, we are pulling the plug.


Код библиотеки:

Код: Выделить всё
{$mode objfpc}{$H+}

uses
  Classes
  { add your units here };

function getone:integer;
begin
  result:=1;
end;

exports getone;

end.


И модуля приложения:
Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{ TForm1 }

function getone:integer; stdcall; external 'libproject1.so';

procedure TForm1.Button1Click(Sender: TObject);
begin
  showmessage(inttostr(getone));
end;

initialization
  {$I unit1.lrs}

end.


Подскажите пожалуйста, что может быть не так? :(
ajunta
незнакомец
 
Сообщения: 3
Зарегистрирован: 23.11.2007 23:02:05

Сообщение alexs » 24.11.2007 00:05:05

Я не уверен в правильности - но всёже - а нужно ли объявлять её как stdcall;? В коде библиотеки такого обявления вроде нет.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Сообщение Sergei I. Gorelkin » 24.11.2007 00:13:31

Что при этом в окошке "Debug output" ("вывод отладчика") показывает?
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение ajunta » 24.11.2007 01:12:34

Я не уверен в правильности - но всёже - а нужно ли объявлять её как stdcall;? В коде библиотеки такого обявления вроде нет.


Исправил на
Код: Выделить всё
function getone:integer;stdcall;


ничего не изменилось.

Что при этом в окошке "Debug output" ("вывод отладчика") показывает?


(gdb)

<-gdb-set confirm off>
^done

(gdb)

<-gdb-set new-console off>
&"No symbol table is loaded. Use the \"file\" command.\n"

^error,msg="No symbol table is loaded. Use the \"file\" command."

(gdb)

<-gdb-version>
~"GNU gdb 6.6-debian\n"

~"Copyright (C) 2006 Free Software Foundation, Inc.\n"

~"GDB is free software, covered by the GNU General Public License, and you are\n"

~"welcome to change it and/or distribute copies of it under certain conditions.\n"

~"Type \"show copying\" to see the conditions.\n"

~"There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n"

~"This GDB was configured as \"i486-linux-gnu\".\n"

^done

(gdb)

<-gdb-set env DESKTOP_SESSION=default>
^done

(gdb)

<-gdb-set env DESKTOP_STARTUP_ID=eugene-desktop;1195852228;168106;11966_TIME1851319828>
^done

(gdb)

<-gdb-set env DISPLAY=:0.0>
^done

(gdb)

<-gdb-set env DM_CONTROL=/var/run/xdmctl>
^done

(gdb)

<-gdb-set env GS_LIB=/home/eugene/.fonts>
^done

(gdb)

<-gdb-set env GTK2_RC_FILES=/home/eugene/.gtkrc-2.0-kde:/home/eugene/.kde/share/config/gtkrc-2.0>
^done

(gdb)

<-gdb-set env GTK_RC_FILES=/etc/gtk/gtkrc:/home/eugene/.gtkrc:/home/eugene/.kde/share/config/gtkrc>
^done

(gdb)

<-gdb-set env HOME=/home/eugene>
^done

(gdb)

<-gdb-set env KDE_FULL_SESSION=true>
^done

(gdb)

<-gdb-set env KDE_MULTIHEAD=false>
^done

(gdb)

<-gdb-set env KDE_SESSION_UID=>
~"Setting environment variable \"KDE_SESSION_UID\" to null value.\n"

^done

(gdb)

<-gdb-set env LANG=en_US.UTF-8>
^done

(gdb)

<-gdb-set env LIBGL_DRIVERS_PATH=/usr/lib/dri>
^done

(gdb)

<-gdb-set env LOGNAME=eugene>
^done

(gdb)

<-gdb-set env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games>
^done

(gdb)

<-gdb-set env PWD=/home/eugene>
^done

(gdb)

<-gdb-set env SESSION_MANAGER=local/eugene-desktop:/tmp/.ICE-unix/11956>
^done

(gdb)

<-gdb-set env SHELL=/bin/bash>
^done

(gdb)

<-gdb-set env SHLVL=0>
^done

(gdb)

<-gdb-set env SSH_AGENT_PID=11903>
^done

(gdb)

<-gdb-set env SSH_AUTH_SOCK=/tmp/ssh-haRYI11859/agent.11859>
^done

(gdb)

<-gdb-set env USER=eugene>
^done

(gdb)

<-gdb-set env XCURSOR_THEME=Industrial>
^done

(gdb)

<-gdb-set env XDM_MANAGED=/var/run/xdmctl/xdmctl-:0,maysd,mayfn,sched,rsvd,method=classic>
^done

(gdb)

<-file-exec-and-symbols "/home/eugene/tempo/project12">
~"Using host libthread_db library \"/lib/tls/i686/cmov/libthread_db.so.1\".\n"

^done

(gdb)

<-environment-cd "/home/eugene/tempo/">
^done

(gdb)

<-data-evaluate-expression FPC_THREADVAR_RELOCATE_PROC>
&"No symbol \"FPC_THREADVAR_RELOCATE_PROC\" in current context.\n"

^error,msg="No symbol \"FPC_THREADVAR_RELOCATE_PROC\" in current context."

(gdb)

<info functions FPC_CPUINIT>
&"info functions FPC_CPUINIT\n"

~"All functions matching regular expression \"FPC_CPUINIT\":\n"

~"\n"

~"Non-debugging symbols:\n"

~"0x080a4514 SYSTEM_FPC_CPUINIT\n"

^done

(gdb)

<-gdb-set language pascal>
^done

(gdb)

<info address main>
&"info address main\n"

~"Symbol \"main\" is a function at address 0x80a36c4.\n"

^done

(gdb)

<-break-insert -t *134887108>
^done,bkpt={number="1",type="breakpoint",disp="del",enabled="y",addr="0x080a36c4",func="main",file="project12.lpr",fullname="/home/eugene/tempo/project12.lpr",line="13",times="0"}

(gdb)

<-break-insert FPC_RAISEEXCEPTION>
^done,bkpt={number="2",type="breakpoint",disp="keep",enabled="y",addr="0x080ae6fa",at="<fpc_raiseexception+6>",times="0"}

(gdb)

<-break-insert FPC_BREAK_ERROR>
^done,bkpt={number="3",type="breakpoint",disp="keep",enabled="y",addr="0x080b1b7a",at="<SYSTEM_HANDLEERRORADDRFRAME$LONGINT$POINTER$POINTER+6>",times="0"}

(gdb)

<-break-insert FPC_RUNERROR>
^done,bkpt={number="4",type="breakpoint",disp="keep",enabled="y",addr="0x080b1c7a",at="<SYSTEM_RUNERROR$WORD+6>",times="0"}

(gdb)

<info file>
&"info file\n"

~"Symbols from \"/home/eugene/tempo/project12\".\n"

~"Local exec file:\n"

~"\t`/home/eugene/tempo/project12', file type elf32-i386.\n"

~"\tEntry point: 0x80a35f0\n"

~"\t0x080480f4 - 0x08048107 is .interp\n"

~"\t0x08048108 - 0x08052cb8 is .hash\n"

~"\t0x08052cb8 - 0x0806db28 is .dynsym\n"

~"\t0x0806db28 - 0x0809c177 is .dynstr\n"

~"\t0x0809c178 - 0x0809f746 is .gnu.version\n"

~"\t0x0809f748 - 0x0809f798 is .gnu.version_r\n"

~"\t0x0809f798 - 0x0809f7c8 is .rel.dyn\n"

~"\t0x0809f7c8 - 0x080a0c68 is .rel.plt\n"

~"\t0x080a0c68 - 0x080a0c9b is .init\n"

~"\t0x080a0c9c - 0x080a35ec is .plt\n"

~"\t0x080a35f0 - 0x0824b968 is .text\n"

~"\t0x0824b968 - 0x0824b987 is .fini\n"

~"\t0x0824b988 - 0x0824b98c is .eh_frame\n"

~"\t0x0824c000 - 0x0824c008 is .ctors\n"

~"\t0x0824c008 - 0x0824c010 is .dtors\n"

~"\t0x0824c010 - 0x0824c014 is .jcr\n"

~"\t0x0824c014 - 0x0824c134 is .dynamic\n"

~"\t0x0824c134 - 0x0824c138 is .got\n"

~"\t0x0824c138 - 0x0824cb94 is .got.plt\n"

~"\t0x0824cb94 - 0x082fcc38 is .data\n"

~"\t0x082fcc40 - 0x08315a74 is .bss\n"

^done

(gdb)

<-exec-run>
^running

(gdb)

/home/eugene/tempo/project12: error while loading shared libraries: libproject1.so: cannot open shared object file: No such file or directory

*stopped,reason="exited",exit-code="0177"

(gdb)

<-break-delete 2>
^done

(gdb)

<-break-delete 3>
^done

(gdb)

<-break-delete 4>
^done

(gdb)

<-file-exec-and-symbols >
^done

(gdb)

<info program>
&"info program\n"

~"The program being debugged is not being run.\n"

^done

(gdb)


Вот эта строчка:

/home/eugene/tempo/project12: error while loading shared libraries: libproject1.so: cannot open shared object file: No such file or directory

мне так же непонятна, файл есть. если в приложении меняю имя библиотеки на заведомо ложное, то получаю соотв. сообщение в окне messages, и билд не проходит.
ajunta
незнакомец
 
Сообщения: 3
Зарегистрирован: 23.11.2007 23:02:05

Сообщение Sergei I. Gorelkin » 24.11.2007 01:40:07

Так похоже дело в том, что Линукс из произвольной папки .so не грузит. Надо либо бросить ее в общеизвестную папку (/usr/lib, /usr/local/lib), либо подправить переменную окружения LD_LIBRARY_PATH.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение ajunta » 24.11.2007 13:10:14

Скопировал .so под рутом в /usr/lib/ и /usr/local/lib/, а so в папке с приложением переименовал, получаю следующую ошибку в окне messages:

/usr/bin/ld: cannot find -lproject2
project12.lpr(17,1) Error: Error while linking


удалил из /usr/lib/ - тоже самое.

если исключить строки:
function getone:integer; stdcall; external 'libproject1.so';
showmessage(inttostr(getone));

то запускается нормально. Как поменять LD_LIBRARY_PATH?
ajunta
незнакомец
 
Сообщения: 3
Зарегистрирован: 23.11.2007 23:02:05

Сообщение Sergei I. Gorelkin » 25.11.2007 15:53:18

Вроде бы так же, как и остальные переменные окружения:

LD_LIBRARY_PATH=/home/то-что-нужно; export LD_LIBRARY_PATH

Чтобы не заниматься этим каждый раз, в Slackware можно отредактировать /etc/ld.so.conf и потом выполнить /sbin/ldconfig.
Как это будет выглядеть в Debian - не знаю...
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Роман1971 » 26.11.2007 15:50:36

Попробуйте без дебагера откомпилировать, в некоторых случаях помогало.
Зайдите в "Проект"->"параметры компилятора"->"Связывание"->"Генерировать информацию для GDB (-g)" и отключите эту опцию. Откомпилиуйте "Запуск"->"Собрать всё". Запуск прийдётся сделать не из под IDE(дебагер откажется это сделать), а вручную из под OS. В некоторых случаях, если при компиляции включена эта опция(-g), то теряются адреса в загружаемой библиотеке.
Роман1971
новенький
 
Сообщения: 69
Зарегистрирован: 30.05.2007 09:14:53

Сообщение Uniser » 07.02.2008 12:19:16

а library mylib; писать в начале файла не обязательно?
Uniser
новенький
 
Сообщения: 46
Зарегистрирован: 13.05.2005 23:13:57
Откуда: Украина, Полтава


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 56

Рейтинг@Mail.ru