动态增加字段语句编译成DLL后调用出错,难道是DLL中不支持‘CreateField’吗?(100)

I

iibug

Unregistered / Unconfirmed
GUEST, unregistred user!
经过跟踪,发现是这个话句出现的问题 FieldDefs.Items.CreateField(_DataSet);运行时在DLL中出现错误提示: Field 'XXXX' is not of an unknown type.不用DLL直接调用是没有问题的,难道是在DLL中不支持吗?麻烦各位大侠帮助看一下,谢谢了!function TFrmArea2F1.AddCalcStringField(_FieldName: String; _DataSet: TDataSet; _Size: Integer): Boolean;var i: Integer;begin if (_DataSet = nil) or (Trim(_FieldName) = '') or (_DataSet.FindField(_FieldName) <> nil) then begin Result := False; Exit; end; _DataSet.Close; for i := 0 to _DataSet.Fields.Count -1 do _DataSet.Fields.Free; //释放静态字段 if _Size = 0 then _Size := 20; //设置Size 默认值为20; with TStringField.Create(_DataSet) do begin FieldName := _FieldName; DisplayLabel := _FieldName; Size := _size; //不能设置为0,否则不能置值,导致失败 FieldKind := fkCalculated; DataSet := _DataSet; end; with _DataSet Do begin for i := 0 to FieldDefs.Count -1 do FieldDefs.Items.CreateField(_DataSet); OnCalcFields := MyADOQueryCalcFields; AutoCalcFields := True; //FieldDefs.Update; Open; end; Result := True;end;
 
顶一下,,,,,XP+DELPHI7环境
 
顶一下,高手请出手。。。
 
困扰数日,高手请帮忙,,,
 
先把FieldDefs.Items的TField打出来看看是什么
 
多谢guanyue7613的关注,,字段:bmbh char 4bmmc nchar 20原来是汉字字段名,后改成拼音字段名,,出错提示 Field 'bmbh' is not of an unknown type.不用DLL就可以正常运行的。。
 
未知的类型
 
是不是嫌分少啊,,再加100分,,穷人米少啊!
 
决定要放弃DLL了,或者DLL中根本就不支持这个命令。
 
石沉大海了,,,,
 
最近我也把之前一起用了好久的函数库整成DLL,然后EXE再调用,也会出现类似的问题,有些函数不整成DLL就没问题,整成DLL就有问题,也不知道是什么原因,我也郁闷着现在......
 
说明还是兼容性的问题,细节问题啊!根本没有测试到的BUG!
 
带包编译才行,即使EXE和DLL中引用同一个类型,不带包编译的话,程序也会认为它们不是同一类型的
 
在工程文件的加入ShareMem我用楼主的函数测试没有发现问题,我的开发环境是delphi6+xp我用ADO+SQL Server2000做测试,建了个test表,只有一个字段bmbh char(4)library DLLCreateField;uses ShareMem, DB, Dialogs, SysUtils, Classes;function AddCalcStringFieldDLL(_FieldName: string; _DataSet: TDataSet; _Size: Integer): Boolean;stdcall;begin if (_DataSet = nil) or (Trim(_FieldName) = '') or (_DataSet.FindField(_FieldName) <> nil) then begin Result := False; Exit; end; _DataSet.Close; if _Size = 0 then _Size := 20; //设置Size 默认值为20; with TStringField.Create(_DataSet) do begin FieldName := _FieldName; DisplayLabel := _FieldName; Size := _size; FieldKind := fkCalculated; DataSet := _DataSet; end; _DataSet.Open; Result := True;end;exports AddCalcStringFieldDLL;beginend.测试程序里也要加入ShareMem静态字段在设计阶段就加入到数据集里面unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, DB, ADODB, Grids, DBGrids;type TForm1 = class(TForm) ADOQuery1: TADOQuery; ADOConnection1: TADOConnection; Button1: TButton; DataSource1: TDataSource; DBGrid1: TDBGrid; Button2: TButton; ADOQuery2: TADOQuery; DBGrid2: TDBGrid; DataSource2: TDataSource; ADOQuery1bmbh: TStringField; ADOQuery2bmbh: TStringField; procedure ADOQuery1CalcFields(DataSet: TDataSet); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure ADOQuery2CalcFields(DataSet: TDataSet); private function AddCalcStringField(_FieldName: String; _DataSet: TDataSet; _Size: Integer): Boolean; { Private declarations } public { Public declarations } end;var Form1: TForm1; function AddCalcStringFieldDLL(_FieldName: string; _DataSet: TDataSet; _Size: Integer): Boolean;stdcall; external 'DLLCreateField.dll';implementation{$R *.dfm}function TForm1.AddCalcStringField(_FieldName: string; _DataSet: TDataSet; _Size: Integer): Boolean;begin if (_DataSet = nil) or (Trim(_FieldName) = '') or (_DataSet.FindField(_FieldName) <> nil) then begin Result := False; Exit; end; _DataSet.Close; if _Size = 0 then _Size := 20; //设置Size 默认值为20; with TStringField.Create(_DataSet) do begin FieldName := _FieldName; DisplayLabel := _FieldName; Size := _size; FieldKind := fkCalculated; DataSet := _DataSet; end; _DataSet.Open; Result := True;end;procedure TForm1.ADOQuery1CalcFields(DataSet: TDataSet);begin if DataSet.FieldByName('bmmc')<>nil then DataSet.FieldByName('bmmc').AsString:='TEST';end;procedure TForm1.Button1Click(Sender: TObject);begin //在exe里直接创建计算字段 AddCalcStringField('bmmc',ADOQuery1,20);end;procedure TForm1.Button2Click(Sender: TObject);begin //在dll里创建计算字段 AddCalcStringFieldDLL('bmmc',ADOQuery2,20);end;procedure TForm1.ADOQuery2CalcFields(DataSet: TDataSet);begin if DataSet.FieldByName('bmmc')<>nil then DataSet.FieldByName('bmmc').AsString:=IntToStr(DataSet.RecNo);end;end.
 
顶部