Wykorzystanie biblioteki napisanej w C

0

Cześć!
Na wstępie przepraszam jeśli powinno trafić do Newbie ale wydaje mi się że nie będę pytał o takie podstawy.

Mija chyba z 9 lat jak przestałem programować w Delphi - zająłem się web'em i grafiką.
Teraz pojawiła się potrzeba wykorzystania pewnej biblioteki (chce postawić bardzo prosty serwer zwracający JSONa na podstawie tego co zwróci dll'ka).

Biblioteka to "Morfeusz": http://sgjp.pl/morfeusz/
Na windows jest dostępny do pobrania skompilowany program wraz z dllką.

Mam od tego taki kod źródłowy:

  struct _InterpMorf {
    int p, k; /* number of start node and end node */
    char *forma, /* segment (token) */
         *haslo, /* lemma */
         *interp; /* morphosyntactic tag */
  };
  typedef struct _InterpMorf InterpMorf;

[...]

  /* Analyse a piece of text:
     'tekst' - the string to be analysed. [...]
     RETURNS a  table of  InterpMorf structures representing  edges of
     the  resulting  graph.
  */
DLLIMPORT InterpMorf *morfeusz_analyse(char *tekst);

Teraz pytanie: czy mogę tę dllkę wykorzystać w programie pisanym w Lazarusie?
Zakładam że się dla, dlatego próbowałem coś rzeźbić ale kiepsko mi idzie...:

type
    InterpMorf = record
      p : integer;
      k : integer;
      forma : PChar;
      haslo : PChar;
      interp : PChar;
  end;

type TLIST = array of InterpMorf;
type TLISTPtr = ^TLIST;       

{...}

var h: Thandle;
    morfeusz_analyse: function(tekst: PChar) : TLISTPtr;
    r: TLISTPtr;
 begin
   h := LoadLibrary('morfeusz2.dll');
   if h >= 32 then
   begin
     Pointer(morfeusz_analyse) := GetProcAddress(h, 'morfeusz_analyse');

     r := morfeusz_analyse('Ten łańcuch jest testem a Ala będzie miała kota');

     showmessage( inttostr(length(r^) ));

     FreeLibrary(h);
   end
   else
     MessageDlg('Error: could not find BAR.DLL', mtError, [mbOk], 0);

end;          
2

Pomyliłeś zwracane typy - funkcja powinna zwracać InterpMorf*, czyli pascalowe ^InterpMorf (we FPC można się potem do tego odnosić jak do tablicy, za pomocą operatora [], w Delphi trzeba afair kombinować z przeliczaniem wskaźników).
Generalnie wszelkie tablice to w 99% przypadkach będzie wskaźnik na strukturę, praktycznie nigdy array of cośtam.

0

no i jak na moje to nie wiesz, ile elementów ma ta tablica, bo funkcja tego nigdzie nie zwraca

EDIT: chyba, że p lub k to rozmiar

3
    morfeusz_analyse: function(tekst: PChar) : TLISTPtr;

tu prawie na pewno brakuje cdecl;

0

I tak już całkiem na boku - zaleca się, aby używać typu TLibHandle dla uchwytu do biblioteki oraz pary funkcji LoadLibrary i UnloadLibrary zamiast FreeLibrary; To związane jest z przenośnością, ale warto takie rzeczy wiedzieć na przyszłość;

Więcej informacji znajdziesz na ten temat tutaj - Loadlibrary - dynamically loading a dynamic library

0
Patryk27 napisał(a):

funkcja powinna zwracać InterpMorf*, czyli pascalowe ^InterpMorf

Azarien napisał(a):

tu prawie na pewno brakuje cdecl;

Dzięki, pomogło! :)

Dla potomnych:

type
    InterpMorf = record
      p : integer;
      k : integer;
      forma : PChar;
      haslo : PChar;
      interp : PChar;
end;

type InterpMorfPtr =^InterpMorf;
type AnalyseFunc = function(tekst: PChar) : InterpMorfPtr;  cdecl;

{...}

procedure TForm1.Button1Click(Sender: TObject);
var libHandle: TLibHandle; //uses dynlibs
    analyse : AnalyseFunc;
    list: ^InterpMorf;
    data : InterpMorf;
    i:integer;
    item: TListItem;
 begin
   libHandle := LoadLibrary('morfeusz2.dll');

   if libHandle >= 32 then
   begin
     Pointer(analyse) := GetProcAddress(libHandle, 'morfeusz_analyse');

     if Assigned(analyse) then
        begin
             list := analyse('Ten łańcuch jest testem a Ala będzie miała kota');

             for i:=0 to 100 do
             begin
               data := list[i];
               if data.p = -1
                 then break; // ostatni element listy

               item := ListView1.Items.Add();
               item.Caption:= inttostr(data.p);
               item.SubItems.Add( inttostr(data.k));
               item.SubItems.Add( data.forma );
               item.SubItems.Add( data.haslo );
               item.SubItems.Add( data.interp );
             end;
        end
        else MessageDlg('No "morfeusz_analyse()" in morfeusz2.dll !', mtError, [mbOk], 0);

     UnloadLibrary(libHandle);
   end
   else
     MessageDlg('Could not find morfeusz2.dll', mtError, [mbOk], 0);

end;  

1 użytkowników online, w tym zalogowanych: 0, gości: 1