旷世难题,估计没多少人碰见过,急急急急!(50分)

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

hyxic

Unregistered / Unconfirmed
GUEST, unregistred user!
我在主程序传了OleVariant(TClientDataSet.Data)给动态链接库里的OleVariant,赋值给一个TClientDataSet.Data对象后,数值字段的数变了。不是原来的数据,我都晕了,请问各位富翁这到底是怎么回事,帮帮忙,多谢!全部家当都献出来了!
 
这里TClientDataSet.Data:=OleVariant就相当于TClientDataSet.close
TClientDataSet.commandtext:='select * from ...'
TClientDataSet.open
 
其他数据没变,只是数值字段变了
 
olevariant 数据是内部的格式,可能是转换了.猜想
 
改成字符串类型
 
如果原来获取数据的控制是ADOQUERY或者ADOSTOREDPROC的话,考虑是ENABLEBCD的属性问题,建议设为FALSE
类似问题我也碰到过,就数值数据变掉了。
 
绝对不可能变,检查一下你的olevariant变量是否正确使用.
因为在我写程序中大量使用了olevariant,没有任何问题.
我用的是D7 + SQL Server2000.
olevariant是COM标准的数据类型,传递这个是绝对不会出错的,这是MS要保证的.
 
我的主程序是这样的:
var
mData:OleVariant;
begin

ClientDataSet1.Close;

ClientDataSet1.CommandText:='select * from table1';

ClientDataSet1.Open;
mData:=ClientDataSet1.Data;
//在此显示数据时数据没问题
ClientDataSet1.Close;
//然后调用Dll把mData传到Dll里边
end;
//Dll是这样的
function dd(mData:OleVariant):Boolean;Stdcall;
var
sData:TClientDataSet;
begin
sData:=TClientDataSet.Create(nil);
sData.Data:=mData;
//显示到DBGrid时数据变了
end;

//帮解决一下
 
mData:=ClientDataSet1.Data;
//在此显示数据时数据没问题
ClientDataSet1.Close;
//然后调用Dll把mData传到Dll里边
我觉得是估计是引用赋值,不是内存复制. 你不ClientDataSet1.Close;
然后传入
DLL 等待dll 处理完成再ClientDataSet1.Close;
看看
 
客户端是不应该有SQL语句的,SQL语句应该在中间层使用.
基本上在界面层中只进行简单的数值合法性判断,操作逻辑判断.然后就不应该在界面层中有其它类型的代码了.
应该是将olevariant传入中间层.中间层处理完后,再将用olevariant返回给界面使用.
 
这样的执行效率太低。
 
有没有解决办法呀!!!!!!!!
 
我才看清题目,你是用的是动态链接库还是com组件,虽然它们都是dll,但本质上它们是不一样的.我上面的回复是针对com组件的.
 
我用的是动态链接库
 
olevariant是COM的标准数据类型,在com组件之间可以自由传输,使用也很简单.
动态链接库中olevariant怎么用我就没办法帮你了.
感觉你这程序还是有点怪,ClientDataSet是在客户端使用,它本身就是一个数据集,为什么你又在dll中创建了一个ClientDataSet,你是不是想传递一个数据集对象???
 
function dd(mData:OleVariant):Boolean;Stdcall;
var
sData:TClientDataSet;
begin
sData:=TClientDataSet.Create(nil);
sData.Data := null;
//加这一句试试?
sData.Data:=mData;
//显示到DBGrid时数据变了
end;
 
to:dcx0026
按照您的方法问题依旧啊!
 
为什么不在dll中GetData呢?
 
(EXE )...EXE中有一模板窗体 uBASE,数据模块 uDM,公用函数 upublic
uDM中包括一个 adoconn , adoquery1 (都已经连接好了)
(upublic中有两个函数,opensql,exesql)
---------------------------------------------------------------------------------------------
type
InvokeDLLForm = function(App: TApplication;
Scr: TScreen): TForm;

TfrmMain = class(TForm)
sbar: TStatusBar;
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
ADOConnection1: TADOConnection;

procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmMain: TfrmMain;
username:string;
conn:TADOConnection;
DLLForm: TForm;

implementation
uses datamodel, upublic;

{$R *.dfm}
procedure sendbj(H: THandle;
M: String);
stdcall;
external 'mydllb.dll';

procedure TfrmMain.Button1Click(Sender: TObject);
var
DLLHandle: THandle;
DLLSub: InvokeDLLForm;
begin

DLLHandle := LoadLibrary('mydllb.dll');
if DLLHandle <> 0 then

begin

@DLLSub := GetProcAddress(DLLHandle, 'CreateDLLForm');
if Assigned(DLLSub) then

begin

DLLForm := DLLSub(Application, Screen);
end;

end;

end;

procedure TfrmMain.Button2Click(Sender: TObject);
begin

sendbj(Application.Handle,dm.conn.ConnectionString);
end;

end.

--------------------------------------------------------------------------------
(upublic中有以下两个函数)
procedure opensql(sqltext:string);
begin

with dm.qrypub do

begin

close;
sql.Clear;
sql.Text := sqltext;
open;
end;

end;

procedure exesql(sqltext:string);
begin

with dm.qrypub do

begin

close;
sql.Clear;
sql.Text := sqltext;
ExecSQL;
end;

-------------------------------------------------------------------------------

dll文件(其中包括一个MID窗体 like
library mydllb;
uses
SysUtils,
Forms,
Windows,
Messages,
Classes,
dll_b in 'dll_b.pas' {frmdllb},
like in 'like.pas' {frmlike};

{$R *.res}
var
DLLApp: TApplication;
DLLScr: TScreen;

function CreateDLLForm(App: TApplication;
Scr: TScreen):TForm;
var
ptr:PLongInt;
begin

Application := App;
Screen := Scr;
Application.CreateForm(Tfrmlike, frmlike);
result:=frmlike;
end;

procedure ExitDLL(Reason: Integer);
begin

if Reason = DLL_PROCESS_DETACH then

begin

Application := DLLApp;
Screen := DLLScr;
end;

end;


exports
CreateDLLForm;

begin

DLLApp := Application;
DLLScr := Screen;
DLLProc := @ExitDLL;
end.


------------包含的窗体---------------------

unit like;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,Db, ADODB, StdCtrls, Menus,
Grids, DBGrids;

type
Tfrmlike = class(TForm)
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Label1: TLabel;

procedure FormClose(Sender: TObject;
var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

procedure sendbj(H: THandle;
M: String);
stdcall;

var
ADOConnection1: TADOConnection;
frmlike: Tfrmlike;

implementation
uses datamodel, upublic;

{$R *.dfm}
procedure sendbj(H: THandle;
M: String);
stdcall;
begin

Application.Handle := H;
{ 将过程的句柄赋值为调用者的句柄 }
ADOConnection1.ConnectionString := M;
// ShowMessage('m');
end;

procedure Tfrmlike.Button1Click(Sender: TObject);
begin

opensql('select id,ht,co from jxdata');
end;

end.

1:怎么能让在Button1Click的事件中获得EXE里的数据模块里的ADOCONN,和ADOQUERY,
怎么样获得EXE里的函数窗体里的OPENSQL , 并且在这里正常运行它?
2:DLL中有一些窗体原本是继承于EXE里的BASE窗体,因为有多级继承,要怎么处理,才能继续有用?
如EXE里有BASE(底层),BASE2继承自BASE,BASE21继承自BASE2,BASE3继承自BASE21,
而DLL中如A窗体继承自BASE2,B窗体继承自BASE3,怎么弄能继续有用?
3:DLL中怎么做能取到EXE里的变量及函数使用呢?
 
to thrhxm:我的是主程序调用的,主程序连接的是远程数据库,所以只能把数据传给数据处理模块(Dll)进行处理,然后再返回处理后的数据。
 
后退
顶部