опять библиотеки

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

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

Ответить
Аватара пользователя
minoshi
постоялец
Сообщения: 279
Зарегистрирован: 17.05.2008 21:23:38

опять библиотеки

Сообщение minoshi »

народ, скажите мне, где ошибка?

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

Код: Выделить всё

library asd;

{$mode objfpc}{$H+}

uses
  Classes, dialogs,
  SysUtils, ExtCtrls;
 
  { you can add units after this }
 
procedure valid(owner : tcomponent; var s : string);stdcall;
begin
 showmessage('hello from library');
end;

exports
       valid;
begin
end.



код вызываемой программы :

Код: Выделить всё

unit Unit1; 

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources,
  dynlibs, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }
  sproc = procedure (owner : Tcomponent; var s : string);
 
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  dllh : Tlibhandle;
  valid2 : sproc;

implementation

{ TForm1 }


procedure TForm1.Button1Click(Sender: TObject);
begin
 dllh := loadlibrary('mylib/asd.so');
 if dllh = 0 then showmessage('not loaded')
 else
 begin
   showmessage('loaded');
   pointer(valid2) := GetProcAddress(dllh, 'valid');
   valid2(application, s);
 end;
end;


procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  if dllh <> 0 then
       begin 
          UnLoadLibrary(dllh);
          showmessage('unloaded');
       end;
end;

initialization
  {$I unit1.lrs}
end.


все компилируется, но когда нажимаем button1
программа показывает, что библиотека загружена (срабатывает showmessage('loaded'); ).
но далее я получаю ошибку " Project raised exception class 'External: SIGSEGV' "

чего я уже попробывал:
копирование библиотеки в /lib и /usr/lib
убирал stdcall;
множество других мелких извращений, о которых и вспоминать не хочется

данный пример неплохо срабатывает в kylix и delphi (единственное там вместо pointer(valid2):=GetProcAddress(dllh,'valid') используется @valid2 := GetProcAddress(dllh,'valid') ).

Народ, спасите мои нервы, ибо четвертый день е**сь(РАди проверки в kylix даже нашел и поставил Altlinux compact!).
Хочется и дальше программировать в Лазаре, то этот тупик просто бесит ...

Если не трудно перепишите этот код, как он должен быть .

Mandriva 2007 free, lazarus 0.9.24, fpc 2.2.0, В Параметрах Лазаря не лазил (все по умолчанию - может там чего поменять нада?).


Доброго времени суток
Alexandre Minoshi
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

Попробуй отказаться от передачи типа string. Используй либо ShortString либо PChar (не помню как с разделяемым менеджером памяти сейчас обстоят дела в fpc)
Аватара пользователя
*vmr
постоялец
Сообщения: 168
Зарегистрирован: 08.01.2007 00:46:07
Откуда: Киев
Контактная информация:

Сообщение *vmr »

Код: Выделить всё

procedure valid(owner : tcomponent; var s : string);stdcall;

Две ошибки да и в одной строчке :)
Подсказка: stdcall сдесь не при чем :D
Аватара пользователя
minoshi
постоялец
Сообщения: 279
Зарегистрирован: 17.05.2008 21:23:38

Сообщение minoshi »

*vmr писал(а):

Код: Выделить всё

procedure valid(owner : tcomponent; var s : string);stdcall;

Две ошибки да и в одной строчке :)
Подсказка: stdcall сдесь не при чем :D


procedure valid (owner : tcomponent);
procedure valid;
меняли stdcall на cdecl;

(все это не помогает)
Аватара пользователя
B4rr4cuda
энтузиаст
Сообщения: 693
Зарегистрирован: 28.12.2007 06:48:35

Сообщение B4rr4cuda »

minoshi писал(а):procedure valid (owner : tcomponent);
procedure valid;
меняли stdcall на cdecl;

Менять надо было string на pchar, не использовать TComponent и прочие классы в экспортируемых процедурах и уж тем более не передавать application, как параметр в библиотеку - все это может привести к непредсказуемым результатам.
Далее :

Код: Выделить всё

pointer(valid2) := GetProcAddress(dllh, 'valid');

лучше заменить на

Код: Выделить всё

valid2 := sproc(GetProcAddress(dllh, 'valid'));


ShowMessage и прочие элементы LCL (формы, диалоги и т.д.) в библиотеке лучше не использовать.
Я с этим поэкспериментировал - результат нехороший. Плохо оно работает. Неудовлетворительно.
Надо выводить сообщения из библы - используем оригинальные интерфейсы (gtk,qt,winapi и тд).

И вообще, по поводу плагинов (модулей) глянь исходники Double Commander-a, конкретно модули uwlxmodule, uwlxprototypes и ./plugins/wlx/ - можешь поковырять рабочие примеры.

Добавлено спустя 9 минут 13 секунд:
И ещё (только что заметил)
Вместо

Код: Выделить всё

type sproc = procedure (owner : Tcomponent; var s : string);

надо (!!!)

Код: Выделить всё

type sproc = procedure (owner : Tcomponent; var s : string); stdcall;
Павел Ишенин
постоялец
Сообщения: 475
Зарегистрирован: 24.03.2007 09:16:52

Сообщение Павел Ишенин »

Я еще заметил, что библиотека не использует Interfaces, который создает Widgetset, а для ShowMessage он нужен. Поэтому AV очень логичен.
Аватара пользователя
Attid
долгожитель
Сообщения: 2589
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E
Контактная информация:

Сообщение Attid »

[оффтоп]
надо организовать конкурс кто больше все заметит ошибок =)
the_beginer
новенький
Сообщения: 30
Зарегистрирован: 29.05.2008 16:51:51

Сообщение the_beginer »

B4rr4cuda писал(а):... не использовать TComponent и прочие классы в экспортируемых процедурах и уж тем более не передавать application, как параметр в библиотеку - все это может привести к непредсказуемым результатам.


т.е. создать с помощью lazarus библиотеку, которая при загрузке сама создаст панель с ... ну пусть будет пара кнопок и memo ... и передаст эту панель на главную форму - все это невозможно?
Аватара пользователя
B4rr4cuda
энтузиаст
Сообщения: 693
Зарегистрирован: 28.12.2007 06:48:35

Сообщение B4rr4cuda »

the_beginer писал(а):и передаст эту панель на главную форму - все это невозможно?

Ну почему невозможно? Возможно. См сюда
Ответить