使用list,records,dll时Delphi中的访问冲突

时间:2015-12-31 02:01:59

标签: list delphi dll access-violation records

我有一个dll和主程序,当我运行主程序时,我收到消息“地址访问违规...”。 在创建表单时,动态包含Dll。 所有代码都是用Delphi编写的。

当我在主程序中使用来自dll的代码时,它可以工作,所以问题在于dll和主程序之间的连接,或者仅在dll中。 有什么想法吗?

主程序:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Grids;

type
  plist = ^recordtype;
  recordtype = record
    surname:shortstring;
    name:shortstring;
    nr:integer;
    group:shortstring;
    wsk:plist;
  end;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    ListBox1: TListBox;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Label5: TLabel;
    StringGrid1: TStringGrid;
    procedure Button3Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
   // procedure StringGrid1FixedCellClick(Sender: TObject; ACol, ARow: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  first: plist;
  rowsvalue: integer;
  dll_handle: HModule;
  insertNode : procedure (a:recordtype ; var first: plist); stdcall;
  read_from_file_to_list: procedure (var rows: integer); stdcall;
  save_list_to_file: procedure (); stdcall;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  person: recordtype;
begin
  person.surname := Edit1.Text;
  person.name := Edit2.Text;
  person.nr := strtoint(Edit3.Text);
  person.group := Edit4.Text;
  insertnode(person, first);
  inc(rowsvalue);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  cur: plist;
  rownr: integer;
  person: recordtype;
begin
  listBox1.Items.Clear();
  cur := first;
  rownr := 1;
  //StringGrid1.RowCount := rowsvalue + 1;
  label1.Caption := first^.surname;
  //StringGrid1.Fixedrows := 1;

  with StringGrid1 do
  begin
    Cells[0,0] := 'Lp.';
    Cells[1,0] := 'Surname';
    cells[2,0] := 'Name';
    cells[3,0] := 'Nr';
    cells[4,0] := 'Group';
  end;
  while (cur <> nil) do
  begin
    person.surname := cur^.surname;
    person.name := cur^.name;
    person.nr := cur^.nr;
    person.group := cur^.group;
    cur := cur^.wsk;
    ListBox1.Items.Add(person.surname);
    ListBox1.Items.Add(person.name);
    ListBox1.Items.Add(IntToStr(person.nr));
    ListBox1.Items.Add(person.group);
    ListBox1.Items.Add('-----------');
    with StringGrid1 do
    begin
      Cells[0,rownr] := IntToStr(rownr);
      Cells[1,rownr] := person.surname;
      cells[2,rownr] := person.name;
      cells[3,rownr] := IntToStr(person.nr);
      cells[4,rownr] := person.group;
    end;
    inc(rownr);
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  save_list_to_file();
  freelibrary(dll_handle);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  save_list_to_file();
  close;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  rows: integer;
  rowsvalue: integer;
begin
  dll_handle := Loadlibrary('bibl_dll.dll');
  @insertNode := GetProcAddress(dll_handle, PChar(1));
  @read_from_file_to_list := GetProcAddress(dll_handle, PChar(2));
  @save_list_to_file := GetProcAddress(dll_handle, PChar(3));
  read_from_file_to_list(rows);
  rowsvalue := rows;
end;

end.

DLL:

library bibl_dll;

uses
  SysUtils, System.Classes;

type
  plist = ^recordtype;
  recordtype = record
    surname: shortstring;
    name: shortstring;
    nr: integer;
    group: shortstring;
    wsk: plist;
  end;

{$R *.res}

var
  first: plist;
  file: file of recordtype;
  person: recordtype;

procedure insertNode(a: recordtype ; var first: plist); stdcall; 
var
  prev, cur: plist;
begin
  cur := first;
  if first = nil then
  begin
    new(first); 
    first^.surname := person.surname;
    first^.name := person.name;
    first^.nr := person.nr;
    first^.group := person.group;
    first^.wsk := nil;
  end
  else 
    if person.nr <= first^.nr then
    begin
      new(cur);
      cur^.surname := person.surname;
      cur^.name := person.name;
      cur^.nr := person.nr;
      cur^.group := person.group;
      cur^.wsk := first;
      first := cur;
    end
    else begin
      while (cur^.wsk <> nil) and (person.nr > cur^.wsk^.nr) do
        cur := cur^.wsk;
      prev := cur;
      new(cur);
      cur^.surname := person.surname;
      cur^.name := person.name;
      cur^.nr := person.nr;
      cur^.group := person.group;
      cur^.wsk := prev^.wsk;
      prev^.wsk := cur;
    end;
end;

procedure read_from_file_to_list(var rows: integer); stdcall;
begin
  Assignfile(file, 'records.dat');
  if not FileExists('records.dat') then
    Rewrite(file)
  else
    Reset(file);
  rows := 0;
  while not eof(file) do
  begin
    Read(file, person);
    InsertNode(person, first);
    inc(rows);
  end;
  CloseFile(file);
end;

procedure save_list_to_file(); stdcall;
var
  cur: plist;
begin
  Assignfile(file, 'records.dat');
  if not FileExists('records.dat') then
    Rewrite(file)
  else
    Reset(file);
  cur := first;
  while (cur <> nil) do
  begin
    person.surname := cur^.surname;
    person.name := cur^.name;
    person.nr := cur^.nr;
    person.group := cur^.group;
    cur := cur^.wsk;
    Write(file, person);
  end;
  closefile(file);
end;

exports
  insertNode index 1,
  read_from_file_to_list index 2,
  save_list_to_file index 3;

begin

end.

0 个答案:

没有答案