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@lists.freepascal.org > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal