[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