Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2006-10

Linux library access violation

5 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Chris

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]));
  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

Reply by email

L
to Chris
Show quoted text 8 lines
int testreturn(const char *thename, char *rcity, char *rstate) { memcpy (rcity,"Boston",7); memcpy (rstate,"Massachusetts",14); return strlen(thename); }

First thing to check.... is it declared CDECL or STDCALL in the C library?

Show quoted text 9 lines
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.

Whelp..exceptions are a false sense of security, and many elite programmers refuse to use them because they are like GOTO statements (Chen, Spolsky, and others). It's even worse when you cover things up like using

  //do something

instead of handling the exception. Whereas if you skip exceptions all together, and just do real checks with regular code, old school error codes - it might end up being more of a solid program. However, this is no place for exception pros/cons flamewars ;-)

In general, for troubleshooting a problem in these beginning stages, I wouldn't even use exceptions - they just complicate things until you find the error using other trial and error code checks such as:
- nil checks.. is something nil, why?
- length checks.. is the pchar the right length before and after, or is it damaged somewhere?
- sizeof checks..
- declaration checks
- operating system error checks such as getlasterror (in this case it don't help, but in general)
- other trial and error through real code instead of exception code

Reply by email

L505
to Chris: I get an "Access violation" when I call a function from a C library. Not sure if I can…
Show quoted text 8 lines
int testreturn(const char *thename, char *rcity, char *rstate) { memcpy (rcity,"Boston",7); memcpy (rstate,"Massachusetts",14); return strlen(thename); }

First thing to check.... is it declared CDECL or STDCALL in the C library? I think the default C declaration mode is CDECL if it is not defined explicitely.

Show quoted text 9 lines
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.

Whelp..exceptions are a false sense of security, and many elite programmers refuse to use them because they are like GOTO statements (Chen, Spolsky, and others). It's even worse when you cover things up like using

  //do something

instead of handling the exception. Whereas if you skip exceptions all together, and just do real checks with regular code, old school error codes - it might end up being more of a solid program. However, this is no place for exception pros/cons flamewars ;-)

In general, for troubleshooting a problem in these beginning stages, I wouldn't even use exceptions - they just complicate things until you find the error using other trial and error code checks such as:
- nil checks.. is something nil, why?
- length checks.. is the pchar the right length before and after, or is it damaged somewhere?
- sizeof checks..
- declaration checks
- operating system error checks such as getlasterror (in this case it don't help, but in general)
- other trial and error through real code instead of exception code

Reply by email

Leducq Dominique
to Chris: I get an "Access violation" when I call a function from a C library. Not sure if I can…

Le Lundi 30 Octobre 2006 01:13, Chris a écrit :

Show quoted text 67 lines
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.

Show quoted text 32 lines
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 - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Chris
L505 wrote: First thing to check.... is it declared CDECL or STDCALL in the C library? I think the default C declaration mode is CDECL if it is not defined

explicitely.

I knew it was gonna be the obvious. I changed:
function testreturn(thename:pchar;rcity:pchar;rstate:pchar):integer;
stdcall; external 'libTester';
to
function testreturn(thename:pchar;rcity:pchar;rstate:pchar):integer;
cdecl; external 'libTester';

and all is good.

Thank you very much ;)

Reply by email