求助!!!DLL调用出错,报无效的指针操作(50分)

  • 主题发起人 主题发起人 yanzhong
  • 开始时间 开始时间
Y

yanzhong

Unregistered / Unconfirmed
GUEST, unregistred user!
总是提示“Invalid pointer operation”,但DLL里的值还能传过来
感觉没有释放,不知无何解决,谢谢了

动态库的程序:
library demo;

type
TPerson=record
PersonNo:string;
PersonName:string;
end;

{$R *.RES}

function RInfo(var PersonInfo:TPerson):integer;stdcall;
begin
PersonInfo.PersonNo:='029832_1';
PersonInfo.PersonName:='张三';
Result:=1;
end;

exports
RInfo index 1 name 'RInfo';
begin
end.

调用DLL的程序:
unit test;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, db,
DBTables;


type
TPerson=record
PersonNo:string;
PersonName:string;
end;

TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;


function RInfo(var PersonInfo:TPerson):integer;stdcall;
far;external 'demo.dll' name 'RInfo'; //读信息

implementation
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
t1:TPerson;
begin
RInfo(t1);
Memo1.Lines.Add('PersonNo:'+t1.PersonNo);
Memo1.Lines.Add('PersonName:'+t1.PersonName);
end;

end.
 
DLL声明改为:
exports
RInfo;
begin
end.

调用方声明改为:
function RInfo(var PersonInfo:TPerson):integer;stdcall;external 'demo.dll'; //读信息
试试看。
 
把你的工程文件打开,改成这样:
program (你的工程名);

uses
sharemem,//这个很重要
Forms,...
再把你的DLL文件打开,改成这样:
library (你的DLL工程名);
uses
sharemem,//这个同样很重要
SysUtils,
Classes;
 
t1:TPerson; t1没分配空间把 没创建

procedure TForm1.Button1Click(Sender: TObject);
var
t1:TPerson;
begin
new(t1);不知道还是 //t1:=TPerson.create(nil);
RInfo(t1);
Memo1.Lines.Add('PersonNo:'+t1.PersonNo);
Memo1.Lines.Add('PersonName:'+t1.PersonName);
end;

end.
 
按照你说的加进去后操作正常,但退出程序还是提示“Invalid pointer operation”,不知何故,麻烦试试,不胜感激
 
record是不需要分配的
 
在释放看看
 
pPerson=^TPerson;
TPerson=record
PersonNo:string;
PersonName:string;
end;
我都喜欢这样用的
 
t1:TPerson; t1没分配空间把 没创建

procedure TForm1.Button1Click(Sender: TObject);
var
t1:TPerson;
begin
new(t1);不知道还是 //t1:=TPerson.create(nil);
RInfo(t1);
Memo1.Lines.Add('PersonNo:'+t1.PersonNo);
Memo1.Lines.Add('PersonName:'+t1.PersonName);
dispose(t1);
end;
end.
你试试
 
t1:TPerson;记录类型,不用new
 
library demo;

type
pTPerson = ^TPerson;
TPerson=record
PersonNo:string;
PersonName:string;
end;


function RInfo(var PersonInfo:TPerson):Pointer;stdcall;
begin

PersonInfo.PersonNo:='029832_1';
PersonInfo.PersonName:='张三';
Result:= @PersonInfo;
end;

exports
RInfo;
begin
end.

调用程序:
unit test;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;


type
pTPerson = ^TPerson;
TPerson=record
PersonNo:string;
PersonName:string;
end;

TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
type
TRInfo=function(t1: TPerson): Pointer;
var
t1:TPerson;
pt1: pTPerson;
LibHandle: Integer;
ProcRInfo: TFarProc;
begin
LibHandle := LoadLibrary(PChar('demo.dll'));
if LibHandle <> 0 then
begin
ProcRInfo := GetProcAddress(LibHandle, PChar('RInfo'));
if @ProcRInfo <> nil then
pt1 := TRInfo(ProcRInfo)(t1);
end;
Memo1.Lines.Add('PersonNo:' + pt1^.PersonNo);
Memo1.Lines.Add('PersonName:' + pt1^.PersonName);
FreeLibrary(LibHandle);
end;

end.

用动态加载dll方式可以
 
不要选中BUILD WITH RUNTIME PACKAGE试一下,看行不行,我前面在试用的也有这个提示,但是我不选中就没有,不知什么原因
 
接受答案了.
 
草。。。。分的分呢
 
给你分了
 
后退
顶部