调用DLL传输String,关闭程序时出错(100分)

  • 主题发起人 主题发起人 ricleon
  • 开始时间 开始时间
R

ricleon

Unregistered / Unconfirmed
GUEST, unregistred user!
以下是DLL及调用程序,在关闭调用程序时出错,还请高手指点!!!
//DLL内的两个单元
//单元1
library KeyBoradHook;

uses
SysUtils,Windows,
Classes,ShareMem,
Unitdll in 'Unitdll.pas';

{$R *.res}

exports
GetConString;

begin

end.


//单元2
unit Unitdll;

interface
function GetConString(DatePath,OptionPath:String):string;stdcall;
implementation
function GetConString(DatePath,OptionPath:String):string;stdcall;
var ConString:string;
begin
Result:='';
ConString:='aaaaaa'+
DatePath+'bbbbbb'+
OptionPath+'cccccc';
Result:=ConString;
end;
end.


//调用单元
unit Unit1;

interface

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

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

var
Form1: TForm1;

implementation
function GetConString(DatePath,OptionPath:String):string; stdcall; external 'KeyBoradHook.dll';
{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Text:=GetConString('d:/ddd','E:www');
end;

end.
 
在Dll里使用String字符类型,必须在你的Dll工程文件(*.dpr)uses最前面放置ShareMem单元。
{ 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. }
 
已经放置了,难道需要最前面?
 
放在最前也是不行。。。
 
把参数改成pchar型就可以了,ShareMem还是放在最前面吧
 
dll和主程序都要放,且要放在dpr文件内,而不是放到pas文件内。
而且,发布程序时候要带上 BORLNDMM.DLL

或者不用string类型输入输出,改pchar类型,那就不用加单元不用带额外的dll
 
放在最前也是不行。。。
 
仍然出错
 
[blue]// 你将下面的代码再试试。红色部分是我更改的。[/blue]
library KeyBoradHook;

uses
[red]ShareMem,[/red]SysUtils,Windows, [blue]//必须在Library最前面放置ShareMem[/blue]
Classes,
Unitdll in 'Unitdll.pas';

{$R *.res}

exports
GetConString;

begin

end.


//单元2
unit Unitdll;

interface
function GetConString(DatePath,OptionPath:String):string;stdcall;
implementation
function GetConString(DatePath,OptionPath:String):string;stdcall;
var ConString:string;
begin
Result:='';
ConString:='aaaaaa'+
DatePath+'bbbbbb'+
OptionPath+'cccccc';
Result:=ConString;
end;
end.


//调用单元
unit Unit1;

interface

uses
[red]ShareMem,[/red]Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls; [blue]//调用主程序也必须在最前面添加ShareMem单元[/blue]

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

var
Form1: TForm1;

implementation
function GetConString(DatePath,OptionPath:String):string; stdcall; external 'KeyBoradHook.dll';
{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Text:=GetConString('d:/ddd','E:www');
end;

end.
 
把string改为widestring
 
在dll输入输出时,还是不要用string类型吧,因为加了共享内存单元后,会引起程序性能下降。当然,内部用用是可以的。
传出数据时,用pchar即可。或者直接传入一个指针,然后在dll内分配内存和填充数据。然后在dll外使用数据后释放内存
 
你要在KeyBoradHook, Unitdll和你调用的project的dpr文件中的Uses的第一个位置上加入
ShareMem;
 
主程序和DLL都需要引用 ShareMem 的。
 

Similar threads

后退
顶部