在dll文件中用 is 的問題(200分)

  • 主题发起人 主题发起人 lqy169
  • 开始时间 开始时间
L

lqy169

Unregistered / Unconfirmed
GUEST, unregistred user!
在dll 中用 is 是不是有問題?
例如在dll中的一個函數
function testform(Aform:pointer)
var
i:integer;
begin
for i:-0 to Tform(Aform).componentcount-1 do
begin
if Tform(Aform).components is Tdataset then -----這句無法正常判斷
begin
..................
end;
end;
end;

請問有什么辦法解決這個問題
( 不要 if Tform(Aform).components.classname='Tdataset' then 這种方法)
 
把tdataset换成ttable或者tquery试试,
tdataset恐怕不能作为比较的内容。
 
建议不要滥用无类型指针。你的AForm指向的是不是一个窗体的实例,如果不是的话,在
连for语句的循环都进不去。为什么不把AForm的类型定义为TForm呢?
 
if Tform(Aform).components.NAME=您定的名字 then
 
to bianlx, tdataset可以做的
to:Sachow 這不是問題的關鍵
to:yangyugw 你的方法比 classname='Tquery'的更差

請高手現身把

 
我认为这个问题不是在和DLL中或在EXE中的问题,而是对象的实例是否存在的问题。如果
你愿意的话,把程序的能编译的部分贴出来,大家一起分析分析。
 
testform你是怎么样调用的(主要尼的AForm是怎么传输进去的)
 
<<delphi技术手册>>第二章说过
在DLL之间或DLL与EXE之间传递对象的时候,由于DLL和EXE都会保留其本身对类表的拷贝
所以在用IS和AS时会出问题,
 
同意楼上的
在Dll中的Tdataset中不会被认为和vcl中的Tdataset是同一个类。不能用IS和AS。
 
楼上的高见啊!
 
如果在function testform(Aform:pointer)中,AForm指向的是DLL中一个对象的地址(该
对象已经建立),就可以生效,进入后面的语句。而如果指向的是另一个程序中的对象,
由于操作系统对进程地址空间的保护机制,一个进程不能访问另一个进程的地址,以上代码
就不能生效。
 
如果把DLL作成包,上面的代码就可以运行,贴主不妨试试。
 
用了这段代码你就应该明白了:

//DLL程序:
library DllTest2;

uses
Classes,
Forms,
DB,
DataMd in 'DataMd.pas' {DataModule1: TDataModule};

{$R *.res}

procedure InitDM;
//建立数据模块的实例(也就是建立数据集实例的过程)
begin
try
Application.Initialize;
Application.CreateForm(TDataModule1, DataModule1);
except
Application.Terminate;
end;
end;

procedure DestroyDM;
begin
DataModule1.Free;
DataModule1 := nil;
end;

function GetCompCount(Comp: TComponent): Integer;
//获取指定组件里有多少个TDataSet类型的对象
var i,j: Integer;
begin
j := 0;
for i:=0 to Comp.ComponentCount-1 do
begin
if Comp.Components is TDataSet then
Inc(j,1);
end;
Result := j;
end;

function GetCompCount2: Integer;
//获取数据模块里有多少个TDataSet类型的对象
var i,j: Integer;
begin
j := 0;
for i:=0 to DataModule1.ComponentCount-1 do
begin
if DataModule1.Components is TDataSet then
Inc(j,1);
end;
Result := j;
end;

exports
GetCompCount,
GetCompCount2;

begin
InitDM;
end.

//调用程序代码
unit CallMain;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Query1: TQuery;
Query2: TQuery;
Query3: TQuery;
Query4: TQuery;
Query5: TQuery;
Query6: TQuery;
Query7: TQuery;
Query8: TQuery;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

function GetCompCount(Comp: TComponent): Integer
external 'DLLTest2.DLL'
function GetCompCount2: Integer
external 'DLLTest2.DLL'

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
//GetCompCount2访问的是DLL自己内部的地址,所以可以通过
ShowMessage(IntToStr(GetCompCount2))


//而下面这里是要让DLL访问EXE中的地址,由于操作系统的进程空间保护机制,DLL程序
//的GetCompCount函数中,“if Comp.Components is TDataSet”不可能返回True,
//所以下面这一调用是没有结果的。
ShowMessage(IntToStr(GetCompCount(Form1)));
end;

end.

所以,结论是:使用is或as,与DLL或EXE无关。
 
謝謝 我知道為什么不成﹐但我要的是解決的辦法
 
如果是delphi程序调用delphi编写的dll的话,不要用指针,直接传TForm类型的就可以。
不过你要实现的功能我没试过。
 

Similar threads

S
回复
0
查看
896
SUNSTONE的Delphi笔记
S
S
回复
0
查看
873
SUNSTONE的Delphi笔记
S
I
回复
0
查看
477
import
I
I
回复
0
查看
738
import
I
后退
顶部