DLL中能输出类,但输出由DLL内创建的数据集时出错!(100分)

  • 主题发起人 主题发起人 hugang
  • 开始时间 开始时间
H

hugang

Unregistered / Unconfirmed
GUEST, unregistred user!
有谁在DELPHI中遇见这样古怪的问题吗?(在C++BUILDER中可是一切正常的喔!),做一个数据处理的类
如:
library PrjTestOne;
uses
Windows,
Messages,
SysUtils,
Classes,
OneObjectU in 'OneObjectU.pas',
wrapOneObject in 'wrapOneObject.pas',
oneObjectForm in 'oneObjectForm.pas' {frmDataForm},
ObjectFace in 'ObjectFace.pas',
DataObjunit in 'DataObjunit.pas';

{$R *.RES}

begin
end.

----------------------------------------------
unit ObjectFace;

interface
uses Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,DB,DBTables,QuickRpt,ExtCtrls,StdCtrls,
Qrctrls,comctrls,MMSystem,iniFiles,Printers,BDE,Registry,
Provider,DBClient,MConnect,Grids,DBGrids,DBCtrls,OleCtnrs;
type
TIDataObject = class
protected
FSQL:PChar;
FDatabaseName:PChar;
FDataSource:TDataSource;
m_DataSource:TDataSource;
m_Query:TQuery;
public
procedure InitDataObject(DatabaseName:PChar);virtual;export;stdcall;abstract;
procedure ReleaseDataObject();virtual;export;stdcall;abstract;
function Open(SQLStmt:PChar):Longint; virtual;export;stdcall;abstract;
procedure Connect(DataSource:TDataSource);virtual;export;stdcall;abstract;
procedure DisConnect();virtual;export;stdcall;abstract;
end;

unit DataObjunit;

interface
uses Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,DB,DBTables,QuickRpt,ExtCtrls,StdCtrls,
Qrctrls,comctrls,MMSystem,iniFiles,Printers,BDE,Registry,
Provider,DBClient,MConnect,Grids,DBGrids,DBCtrls,OleCtnrs,objectface;
type

TDataObject=class(TIDataObject)
public
procedure InitDataObject(DatabaseName:PChar);override;
procedure ReleaseDataObject();override;
function Open(SQLStmt:PChar):longint; override;
procedure Connect(DataSource:TDataSource);override;
procedure DisConnect();override ;
end;

implementation
procedure TDataObject.InitDataObject(DatabaseName:PChar);
begin
FDatabaseName:=DatabaseName;
m_Query:=TQuery.Create(Application);
m_Query.DatabaseName:=FDatabaseName;
m_DataSource:=TDataSource.Create(Application);
FDataSource:=nil;
end;
procedure TDataObject.ReleaseDataObject();
begin
Disconnect;
m_Query.close;
m_Query.free;
m_Query:=nil;
m_DataSource.free;
m_DataSource:=nil;
FDataSource:=nil;
destroy;
end;
function TDataObject.Open(SQLStmt:PChar):longint;
begin
with m_Query DO begin
close;
DatabaseName:=FDatabaseName;
SQL.Clear;
SQL.Add(SQLStmt);
while not prepared do
prepare();
open;
result:=RecordCount;
end;
m_DataSource.DataSet:=m_Query;
end;
procedure TDataObject.Connect(DataSource:TDataSource);
begin
FDataSource:=DataSource;
FDataSource.DataSet:=m_Query;
end;
procedure TDataObject.DisConnect();
begin
FDataSource.DataSet:=nil;
FDataSource:=nil;
end;
end.

===============

调用的主程序:
unit frmTestDllOne;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids, DBGrids, Db, Buttons, DBTables, ObjectFace;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Query1: TQuery;
BitBtn1: TBitBtn;
Database1: TDatabase;
BitBtn2: TBitBtn;
BitBtn3: TBitBtn;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
private
{ Private declarations }
hObjInst:THandle;
IObj:TIDataObject;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses OneObjectInc;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
sPath:String;
sSQL:String;
iNumRows:longint;
begin
sSQL:='select * from owentipdb where tipno<101';
sPath:='D:/fhx/owentips';
hObjInst:=GetOneObject(PChar(sPath));
if hObjInst>0 then
begin
SetSQL(hObjInst,PChar(sSQL));
//iNumRows:=OpenEx(hObjInst,Query1,DataSource1);
iNumRows:=Open(hObjInst);
ShowMessage(IntToStr(iNumRows));
ConnectDBGrid(hObjInst,DBGrid1);
//SetDataSource(hObjInst,DataSource1);
//ConnectDataSource(hObjInst,DataSource1);
// if GetDataSource(hObjInst)<>nil then
// begin
// ShowMessage('Get datasource object good!');
//DBGrid1.DataSource:=GetDataSource(hObjInst);
// end
// else
// ShowMessage('cannot get Datasource object!');


end
else
showMessage('Error create object!');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
FreeOneObject(hObjInst);
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Query1.Close;
Query1.databaseName:=Database1.DatabaseName; //'D:/fhx/owentips';
Query1.SQL.Clear;
Query1.SQL.Add('select * from owentipdb where tipno<101');
OpenDataSet(Query1,DataSource1);
DBGrid1.DataSource:=DataSource1;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
var
sPath,
sSQL:String;
iNumRows:Longint;
begin
sPath:='c:/fhxb2b/owentips';
sSQL:='select * from owentipdb';
IObj:=GetMyDataObject(PChar(sPath));
iNumRows:=IObj.Open(PChar(sSQL));
showMessage(IntToStr(iNumRows));
IObj.Connect(DataSource1);
end;

procedure TForm1.BitBtn3Click(Sender: TObject);
begin
IObj.releaseDataObject();
IObj:=nil;
end;

end.
这个DLL项目如果换成C++BUIDER代码编译运行,一切正常,可是DELPHI里调用时总是出错,“非法访问”
没有理由的啊!我想可能是DELPHI里DLL进程空间管理出问题了。在DLL内创建的TQUERY提取的数据居然不能
显示在调用程序的DBGRID中,一点理由都没有的!而且DELPHI要从DLL中输出类既然也要做一大堆工作,
实在是烦躁!没有C++方便!
不知道哪位老兄能指出上面程序除非访问的症根所在!
另外就算我在DLL PROJECT里USE SHAREMEM单元后,嘿,居然能显示数据了,当时当我关闭调用表单时又
报告说“INVID POINTER OPERATION!”这这毛病只在你把STRING类型做为EXPORT函数的参数而没有引用
sharemem单元时才会发生的。真叫人搞不懂了,希望某家能给点提示,谢谢!!!

hugang




 
string 类型不要直接输出,转成 PChar 再输出
 
由主进程创建的query传递到 dll中, 由dll执行查询获取数据再交还主进程显示就不会
有问题了.
 
多人接受答案了。
 
后退
顶部