一个调用DLL的问题,200分奉送,请近来,急(200分)

  • 主题发起人 主题发起人 xewei
  • 开始时间 开始时间
X

xewei

Unregistered / Unconfirmed
GUEST, unregistred user!
错误提示:Invalid poniter operation
但是DLL的函数计算出来了,请高手指点。
unit RegSoft;

interface
function GetSerialNumber(var UserName:string):string;stdcall;
function test():string;stdcall;
implementation
uses Sysutils;
const SerialBaseValue = 7756;

function GetSerialNumber(var UserName:string):string;stdcall;
var
i,n:integer;
begin
n := 1;
for i:=1 to length(UserName) do
n := abs((ord(UserName)*n+55555555)) mod 10;
n := n+SerialBaseValue;
Result := copy(inttostr(n),1,8);
end;
function test():string;stdcall;
begin
test := 'successfull';
end;
end.

library cxw;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
SysUtils,
Classes,
RegSoft;

exports
GetSerialNumber,
test;

begin
//SaveExit := ExitProc
// save exit procedure chain
//ExitProc := @LibExit
// install LibExit exit procedure
end.

unit FormSerialCalc;

interface

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

type
TSerialCalcForm = class(TForm)
Label1: TLabel;
edUserName: TEdit;
Label2: TLabel;
edSerialNumber: TEdit;
btnBuild: TButton;
btnExit: TButton;
procedure FormClose(Sender: TObject
var Action: TCloseAction);
procedure btnExitClick(Sender: TObject);
procedure btnBuildClick(Sender: TObject);
private
{ Private declarations }

public
{ Public declarations }
end;

var
SerialCalcForm: TSerialCalcForm;

implementation
function GetSerialNumber(var UserName:string):string;stdcall;external 'cxw.dll';
function test():string;stdcall;external 'cxw.dll';
{$R *.DFM}

procedure TSerialCalcForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
action := cafree;
end;

procedure TSerialCalcForm.btnExitClick(Sender: TObject);
begin
close;
end;

procedure TSerialCalcForm.btnBuildClick(Sender: TObject);
var
strUserName:string;
begin
strUserName := trim(edUserName.Text);
try
edSerialNumber.Text := GetSerialNumber(strUserName);
except
end;
end;

end.
 
Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters.

这段话你仔细看看
 
看了很多DLL的东西,理解不是很透彻,但是如楼上说的,你加上SHAREMEM试试看
 
建议..
1.不要用string而用PChar传递参数及返回值
2.尽量少用var参数,而用Const,如果要传值,用指针
 
用pchar啊。

你一改成pchar立即就好。
以后编DLL记住这一点哦,很少麻烦的。
 
如果在DLL中使用Delphi的字符类型:String来进行传递的时候,
必须Use ShareMem单元,并且ShareMem单元必须是第一个被引用的。
 
不明白,老兄能不能说清楚一些。
具体应该怎么做?
 
uses
ShareMem,//引用ShareMem单元,而且必须是第一个
SysUtils,
Classes,
RegSoft;



unit FormSerialCalc;

interface

uses
ShareMem{引用ShareMem单元},Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

 
function GetSerialNumber(UserName:[red]PChar[/red]):[red]PChar[/red];stdcall;
function test():[red]PChar[/red];stdcall;

function GetSerialNumber(UserName:[red]PChar[/red]):[red]PChar[/red];stdcall;external 'cxw.dll';
function test():[red]PChar[/red];stdcall;external 'cxw.dll';
 
太妙了,我把输入参数和输出参数的类型都改成了PCHAR,就行了
但我看了一些参考书都是用STRING,难道他们都是骗人的吗?
还有其他类型要注意的吗?
 
ShareMem,//引用ShareMem单元
 
不对啊
又有新问题出来了
那就是输入参数改变了,输出值一直不改变
我保证函数没有问题,我在表单里测试过这个函数了
 
多人接受答案了。
 
后退
顶部