błąd wykonywania funkcji z DLL

0

Witajcie.
Napisałam na razie prościutką funkcję ale od razu napotkałam problemy w działaniu. Wygląda to tak:

for x:=1 to 3 do
begin
showmessage(funkcjazdll(ListBox1.Items,ListBox1.Items,ListBox1.Items));
end;
showmessage('wykonanopoprawnie');

ostatni komunikat się wyświetla a po nim jeszcze taki błąd:

Project project1.exe raised exception class 'External: SIGSEGV'

co doprowadza mnie już do szału, bo ile razy robię coś na zmiennych typu TStrings albo TStringList, tyle razy coś mi nie działa zwracając ten błąd i zmuszając do robienia na zakichanych ListBoxach co przy dużej ilości operacji jest baaaardzo powolne :/

to było przy kompilacji, natomiast podczas uruchomienia programu z exe mam:
Acces Violation
OK to ignore or cancel to kill

aghr.... HELP... PLEASE...!!!

0

Bo dllka wymaga przekazywania typów jako PChar, czytaj ostrzeżenie przy tworzeniu nowej dllki, typ string nie jest zalecany. Ale jeśli już musisz przekazać zawartość ListBoxa to nie wiem dlaczego aż trzy razy to samo, ale ja bym to zrobił tak - sprawdziłem i działa. A jeżeli to rozwiązanie Tobie nie odpowiada, to już nie musze dopusywać co ktoś inny może zrobić ;) Ewentualnie sprecyzuj co Twoja funkcja lub procedura w dllce ma robić, pokazując kod.

Kod project2.dll:

library project2;

uses
  Windows, Classes;

procedure Bum(Str : TStrings); stdcall
var
  I : integer;
  SL : TStringList;
begin
  SL := TStringList.Create;
  for I := 0 to Str.Count - 1 do
  begin
    SL.Add(Str[I]);
  end;
  MessageBox(0, PChar(SL.Text), 'Procedura z dll', MB_ICONINFORMATION + MB_OK);
  SL.Free;
end;

exports
  Bum;

begin
end.

Wycinek kodu najważniejszej części programu wykorzystującego project2.dll:

//...
var
  Form1: TForm1;
  Bum : procedure(Str : TStrings); stdcall;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  H : THandle;
begin
  H := LoadLibrary('project2.dll');
  if H > 0 then
  begin
    Bum := GetProcAddress(H, 'Bum');
    if @Bum <> nil then
    begin
      Bum(ListBox1.Items);
    end;
  end;
end;
0

haha :) wpisałam 3x to samo przez pomyłkę :) chciałam, żeby było bardziej czytelnie więc zmieniłam nazwy komponentów na ogólnie zrozumiałe i zapomniałam zmienić na 1,2,3 ;P
Funkcja na razie nie robi nic. Pisząc coś mam nawyk sprawdzania czy działa po każdym dodanym elemencie, toteż zanim zaczęłam pisać funkcję sprawdziłam czy w ogóle cokolwiek działa.
Już sprawdzam Twoje rozwiązanie ;)

0

Może ja mam osłabioną percepcję, ale nie widzę tego... Nie widzę gdzie tu jest przesłanie danych do funkcji i przyporządkowanie jakiejś wartości jej wyniku.
Natomiast kombinowałam na wszelkie możliwe sposoby łącznie z przesyłaniem Rekordu składającego się z array of Integer
i jedno wielkie G!
znaczy się nie wiem jak to się dzieje, że zawsze jak się tykam TStrings to jest ten magiczny nie wiadomo-skąd-błąd :(
przekonwertowałam wszystkie TStringsy na tablice w rekordzie - to działało
ale już wymiana informacji z DLL absolutnie nie.
czy to jest kwestia tego, że pracuję na Lazarusie zamiast na starym poczciwym Delphinie?
i ten "FreeSheet" ma jakieś absurdalne problemy czy o co chodzi?

Zasadniczo funkcja wygląda tak, że na podstawie trzech list, już wszystko jedno jakich, byleby dało się to przesłać do biblioteki i z powrotem ma wygenerować wynik (w sumie też dowolny może być nawet liczba).

Robiłam to na ListBox'ach z tego względu, że niektóre elementy są przenoszone między listami w związku z czym potrzebna mi była opcja usuwania z listy której array nie ma (nie ma? prawda?). Chciałam z Początku TStrings ale właśnie cały czas były te same błędy, więc przerzuciłam się na wolniejsze ListBox'y (zresztą ukryte, żeby pracowały szybciej)

0

używanie tablic dynamicznych (w tym stringów) jako argumentów wywołań funkcji z dll aż prosi się o błędy. możesz dodać do kodu dll unit ShareMem (o ile dobrze pamiętam), albo - co będzie mniej błędogenne - nie używać do komunikacji z dll żadnych postaci tablic dynamicznych (wliczając w to obiekty używające takich tablic lub obiekty używające takich obiektów itp).

0
De eL Elka napisał(a)

Może ja mam osłabioną percepcję, ale nie widzę tego... Nie widzę gdzie tu jest przesłanie danych do funkcji i przyporządkowanie jakiejś wartości jej wyniku.

U mnie Bum to procedura, ale z funkcją też nie byłby problem. A przekazanie parametru do procedury masz tutak:

  Bum(ListBox1.Items);

Co do używania stringów to tak jak napisal LF. Ale jak chcesz funkcją to zrobić to mozna i funkcją. Btw, procedurą też można zwrócić jakieś parametry. Przy niestandardowych typach prostych może nawet lepiej zrobić to przez parametr w procedurze poprzedzony słowem kluczowym var. Przeanalizuj sobie mój przykład, ja zawsze zanim podaje w odpowiedziach czy tutaj czy na innych forach jakiś kod, to staram się go przed odpowiedzią sprawdzić. Kod na pewno działa.

0

Jeszcze istnieją ShortStringi.

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