[fpc-pascal] Linux library access violation
Leducq Dominique
dleducq at magellan-ing.fr
Mon Oct 30 08:41:08 CET 2006
Le Lundi 30 Octobre 2006 01:13, Chris a écrit :
> I get an "Access violation" when I call a function from a C library.
>
> Not sure if I can explain well enough, so I will just post the code:
>
> The C library:
> #include <stdio.h>
> #include <string.h>
>
> int testreturn(const char *thename, char *rcity, char *rstate)
> {
>
> memcpy (rcity,"Boston",7);
> memcpy (rstate,"Massachusetts",14);
>
> return strlen(thename);
> }
>
> The C library is compiled and named libTester.so
>
> The code I call to the function from is:
>
> unit Unit1;
>
> {$mode objfpc}{$H+}
>
> interface
>
> uses
> Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
> StdCtrls,
> Buttons, StrUtils;
>
> type
>
> { TForm1 }
>
> TForm1 = class(TForm)
> Button1: TButton;
> Edit1: TEdit;
> Edit2: TEdit;
> Edit3: TEdit;
> procedure Button1Click(Sender: TObject);
> private
> { private declarations }
> public
> { public declarations }
> end;
>
> var
> Form1: TForm1;
> function testreturn(thename:pchar;rcity:pchar;rstate:pchar):integer;
> stdcall; external 'libTester';
>
> implementation
>
> { TForm1 }
>
> procedure TForm1.Button1Click(Sender: TObject);
> var
> rlines : array[0..1] of string;
> retint : integer;
> ganame : string;
> begin
> ganame := Trim(Edit1.Text);
> rlines[0] := StringOfChar('0', 80);
> rlines[1] := StringOfChar('0', 80);
> retint := testreturn(pchar(ganame), pchar(rlines[0]), pchar(rlines[1]));
the pointers you pass to the function must point to allocated buffers with
enough memory. I think in objfpc/delphi mode string defaults to ansistring,
not shortstring, and then the memory is allocated dynamically, and an empty
string has no memory allocated for the data (check the doc).
Personally, I would:
- check the pointers in the C function before using them;
- pass the buffer sizes to the C function, to avoid buffer overflows.
> Edit2.Text := AnsiLeftStr(rlines[0], pos(Chr(0), rlines[0]) - 1);
> Edit3.Text := AnsiLeftStr(rlines[1], pos(Chr(0), rlines[1]) - 1);
> Form1.Caption := 'Name Length: ' + inttostr(retint);
> end;
>
> initialization
> {$I unit1.lrs}
>
> end.
>
> It works well but, I get a message box that pops up that says "Access
> violation" press OK to continue and risk possible data corruption or
> Cancel to exit.
>
> I click OK and its fine. It returns everything correctly. That message
> box is a pain though. I tried:
> try
> retint := testreturn(pchar(ganame), pchar(rlines[0]), pchar(rlines[1]));
> except
> //do something
> end;
>
> But the program just quits.
>
> Any help?
>
> Thanks
>
>
> _______________________________________________
> fpc-pascal maillist - fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
More information about the fpc-pascal
mailing list