关于调用dll问题,奇怪了~~~~ (100分)

  • 主题发起人 主题发起人 ili
  • 开始时间 开始时间
I

ili

Unregistered / Unconfirmed
GUEST, unregistred user!
DLL文件代码:
library Project2;
uses
ShareMem,
SysUtils,
Classes;

{$R *.res}

function GetRegInfo: string
stdcall;
begin
Result := 'aaa';
end;

exports
GetRegInfo;

begin
end.

EXE文件代码:
unit Unit1;

interface

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

type
TForm1 = class(TForm)
RegInfo: TLabel;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TGetRegInfo = function : string;

var
Form1: TForm1;
CurrentDir: string
{当前绝对路径}
theHandle: THandle;
GetRegIf: TGetRegInfo;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
CurrentDir := GetCurrentDir
{取得当前绝对路径}
{获取注册信息}
theHandle := LoadLibrary(PChar(CurrentDir + '/Project2.dll'));
if theHandle >= 32 then
begin
GetRegIf := GetProcAddress(theHandle, 'GetRegInfo');
RegInfo.Caption := TGetRegInfo(GetRegIf);
FreeLibrary(theHandle);
end;
end
// <-单步运行到这儿出错:Project E:/MyPro/Temp/Project1.exe faulted with message:'access violation at 0x00e60bb4:read of address 0x00e60bb4'.Process Stopped.Use Step or Run to continu.

end.
[red]大哥们救命那!!很急的![/red]
 
应该是你那句FreeLibrary(theHandle);出的问题
 
那该怎么改呢?我是照着书上的做的呀~~
 
function GetRegInfo: string
stdcall;----->string改为widestring,ok!!
begin
Result := 'aaa';
end;
 
真话,书上的不一定对,上面的改为PCHAR类型,试试,WINDOWS的字符串和DELPHI的
字符串不一样
 
虽然A n s i S t r i n g 在外表上跟以前的字符串类型几乎相同,但它是动态分配的并有自动回收功能,正
是因为这个功能A n s i S t r i n g 有时被称为生存期自管理类型。Object Pascal 能根据需要为字符串分配空间,
所以不用像在C / C + +中所担心的为中间结果分配缓冲区。另外,A n s i S t r i n g 字符串总是以n u l l 字符结束
的,这使得A n s i S t r i n g 字符串能与Win32 API 中的字符串兼容。实际上,A n s i S t r i n g 类型是一个指向在堆
栈中的字符串结构的指针。
警告Borland 没有将长字符串类型的内部结构写到文档中,并保留了在Delphi 后续版本中修改
长字符串内部格式的权利。在这里介绍的情况主要是帮助你理解A n s i S t r i n g 类型是怎样工作的
并且在程序中要避免直接依赖于AnisString 结构的代码。
程序员如果在Delphi 1.0 中避免了使用字符串的内部结构,则把代码移植到Delphi 2.0 没有
任何问题。而依赖于字符串内部结构写代码的程序在移植到Delphi 2.0 时必须修改。
正如图2 - 1 演示的,A n s i S t r i n g 字符串类型有引用计数的功能,这表示几个字符串都能指向相同的
物理地址。因此,复制字符串因为仅仅是复制了指针而不是复制实际的字符串而变得非常快。

图2-1 显示了AnsiString 在内存中分配的情况
分配内存长度+引用计数+长度+实际字符串
 
function GetRegInfo: [red]string[/red]
stdcall;

string 该成shortstring 或 pchar
 
Widestring不对呀,运行到:RegInfo.Caption := TGetRegInfo(GetRegIf);就跳出CPU视图了~~
怎么回事?
 
在dll里面最好不要用string
 
TGetRegInfo = function : string;[red]StdCall[/red]
<----加入关键字StdCall
 
To ASCII:
你的方法不对,依然出错,不能运行!

To lsys:
可我加了uses ShareMem单元了呀,string应该可以用的?!
 
同意楼上的,改为pchar
 
看一下你的exe工程文件的第一行是不是引用了sharemem单元。必须把它设为第一个引用单元。
我用dll输出字符串,没问题的。
 
To winion:
这个ShareMem是加在exe的工程文件里而不是dll的么?
 
1、dll用了 function GetRegInfo: string
stdcall
(用了stdcall)
exe就一定要stdcall: TGetRegInfo = function:string;StdCall

2、RegInfo.Caption := TGetRegInfo(GetRegIf)()
(最后面加一对括号)
 
多人接受答案了。
 
后退
顶部