但凭这一句,“fatal error:cannot create application object in a shared object or library",不好说。
library IC_Dll;{ Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. }uses SysUtils, Classes, Forms, Windows, DPunit in '..\..\IC\AP88\Public\DPunit.pas' {DPDM: TDataModule}, unExport in 'unExport.pas', Unit1 in 'Unit1.pas' {Form1}, IC_ErrorMessageUnit in '..\..\IC1\IC_ErrorMessageUnit.pas', untIC_Public in '..\..\IC1\untIC_Public.pas', untIC_LoggerDM in '..\..\IC1\untIC_LoggerDM.pas' {IC_LoggerDM: TDataModule}, untIC_Logger in '..\..\IC1\untIC_Logger.pas', logconfig in '..\..\IC1\logconfig.pas', SearchUnit in '..\..\IC1\SearchUnit.pas' {SearchForm}, uBase64Code in '..\..\IC1\uBase64Code.pas', ModalFrmUnt in '..\..\IC1\ModalFrmUnt.pas' {FrmModal}, ICMFindCardUnt in '..\..\IC1\ICMFindCardUnt.pas' {ICMFindCardForm}, ICCardImpUnt in '..\..\IC1\ICCardImpUnt.pas', DBMetaDataUnt in '..\..\IC1\DBMetaDataUnt.pas', DBDataSetUnt in '..\..\IC1\DBDataSetUnt.pas', AccountImpUnt in '..\..\IC1\AccountImpUnt.pas', MarketAccountImpUnt in '..\..\IC1\MarketAccountImpUnt.pas', AccountManagerImpUnt in '..\..\IC1\AccountManagerImpUnt.pas', ICMUnit in '..\..\IC1\ICMUnit.pas', ICM_untPublic in '..\..\IC1\ICM_untPublic.pas', ICM_untMifareIICCard in '..\..\IC1\ICM_untMifareIICCard.PAS', VendueConst in '..\..\IC1\VendueConst.pas', md5 in '..\..\IC1\md5.pas', Cl_crypt32 in '..\..\IC\AP88\Public\Cl_crypt32.pas';{$R *.res}Exports LoadFrm; var GApplication: TApplication ; GScreen: TScreen;procedure InitDll(dWseason: DWORD); begin case dWseason of DLL_PROCESS_ATTACH: begin GApplication := Application; GScreen := Screen; end; DLL_PROCESS_DETACH: begin Application := GApplication; Screen := GScreen; end; end; end;begin DllProc := @InitDll; InitDll(DLL_PROCESS_ATTACH); end.
unit unExport;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; procedure LoadFrm(App: TApplication; Scr: TScreen); StdCall; implementationuses Unit1,DPunit, DBMetaDataUnt;procedure LoadFrm(App: TApplication; Scr: TScreen ); var LPtr: PLongint; begin if Form1 <> nil then Exit; Application := App; Screen := Scr; LPtr := @Application.MainForm; LPtr^ := Longint(App.MainForm); if DPDM <> nil then DPDM := TDPDM.Create(App.MainForm); DBMetaDataSet := TDBMetaDataSet.Create; Form1 := TForm1.Create(App.MainForm); Form1.Left := (App.MainForm.Width-Form1.Width) div 2 ; Form1.Top := (App.MainForm.Height-Form1.Height) div 2 ; Form1.Show; end;end.
我加了这个单元就调用Dll出错了!,请高手帮我unit DBMetaDataUnt;interface uses Classes, SysUtils, AdoDB, untIC_Public,QDialogs;type TDBColumn = class(TObject) private FTableName:String; FFieldName:String; FChineseName:String; FIsKey:Integer; FIsRepeat:Integer; FIsNull:Integer; FFielddefault:String; FType:String; FLength:Integer; FDisplayLength:Integer; FIsReadOnly:Integer; public constructor Create(const pTableName:String; const pFieldName:String; const pFieldChinaName:String; const pIsKey:Integer; const pIsRepeat:Integer; const pIsNull:Integer; const pfielddefault:String; const pfileldtype:String; const pLength:Integer;const pDisplayLength:Integer; const pIsReadOnly:Integer); published property TableName:String read FTableName; property FieldName:String read FFieldName; property ChineseName:String read FChineseName; property IsKey:Integer read FIsKey; property IsRepeat:Integer read FIsRepeat; property IsNull:Integer read FIsNull; property Fielddefault:String read FFielddefault; property ColumnType:String read FType; property Length:Integer read FLength; property DisplayLength:Integer read FDisplayLength; property IsReadOnly:Integer read FIsReadOnly; end;type TDBObject = class(TObject) private FTableName:String; FChineseName:String; FTableDescription:String; FColumns:array of TDBColumn; function getCount:Integer; public function getColumn(const fieldName:String):TDBColumn;overload; function getColumn(const index:Integer):TDBColumn;overload; constructor Create(const tabName:String;const chName :String;const tabDescr:String); destructor Destroy;override; published property TableName:String read FTableName; property ChineseName:String read FChineseName; property Description:String read FTableDescription; property Count:Integer read getCount; end;type TDBMetaDataSet = class(TObject) private FObjects:array of TDBObject; public function getObject(const objName:String):TDBObject; constructor Create; destructor Destroy;override; end;var DBMetaDataSet:TDBMetaDataSet; implementationconstructor TDBObject.Create(const tabName:String;const chName :String;const tabDescr:String); var adsTemps:TADODataSet; i,count:Integer; begin FTableName := uppercase(tabName); FChineseName := chName; if tabDescr = '' then FTableDescription := tabName else FTableDescription := tabDescr; adsTemps:=untIC_Public.RunDataSet('select FieldName, FieldChinaName, IsKey, IsRepeat, IsNull, fielddefault, type, Length, DisplayLength,IsReadOnly from DPColumns where UPPER(tablename)=UPPER('+quotedStr(tabName)+') order by FieldOrder'); count := adsTemps.RecordCount; if count > 0 then setLength(FColumns,count); begin for i := 0 to count -1 do begin FColumns[i]:=TDBColumn.Create(tabName, adsTemps.fieldbyname('FieldName').asString, adsTemps.fieldbyname('FieldChinaName').asString, adsTemps.fieldbyname('IsKey').asInteger, adsTemps.fieldbyname('IsRepeat').asInteger, adsTemps.fieldbyname('IsNull').asInteger, adsTemps.fieldbyname('fielddefault').asString, adsTemps.fieldbyname('type').asString, adsTemps.fieldbyname('Length').asInteger, adsTemps.fieldbyname('DisplayLength').asInteger, adsTemps.fieldbyname('IsReadOnly').asInteger); adsTemps.Next; end; end; adsTemps.Free; end;destructor TDBObject.Destroy; var i,count:Integer; begin count := length(FColumns); for i :=0 to count -1 do FColumns[i].Free; inherited Destroy; end;function TDBObject.getCount:Integer; begin Result := Length(FColumns); end;function TDBObject.getColumn(const index:Integer):TDBColumn; begin if (index<0) or (index >= Length(FColumns)) then Result := nil else Result := FColumns[index]; end;function TDBObject.getColumn(const fieldName:String):TDBColumn; var i,count:Integer; begin count := length(FColumns); Result := nil; for i :=0 to count -1 do begin if FColumns[i].FFieldName = uppercase(fieldName) then begin Result := FColumns[i]; exit; end; end; end;constructor TDBColumn.Create(const pTableName:String; const pFieldName:String; const pFieldChinaName:String; const pIsKey:Integer; const pIsRepeat:Integer; const pIsNull:Integer; const pfielddefault:String; const pfileldtype:String; const pLength:Integer;const pDisplayLength:Integer; const pIsReadOnly:Integer); begin FTableName:=uppercase(pTableName); FFieldName:=uppercase(pFieldName); if pFieldChinaName = '' then FChineseName:= FFieldName else FChineseName:=pFieldChinaName; FIsKey:= pIsKey; FIsRepeat:=pIsRepeat; FIsNull:=pIsNull; FFielddefault:=pfielddefault; FType:=pfileldtype; FLength:=pLength; FDisplayLength:=pDisplayLength; FIsReadOnly := pIsReadOnly; end;constructor TDBMetaDataSet.Create; var adsDBObj:TADODataSet; i,count:Integer; begin adsDBObj:=untIC_Public.RunDataSet('select TableName,TableChinaName,TableDescribe from DPObjects'); count := adsDBObj.RecordCount; if count > 0 then begin setLength(FObjects,count); for i := 0 to count -1 do begin FObjects[i]:=TDBObject.Create(adsDBObj.fieldbyname('TableName').asString, adsDBObj.fieldbyname('TableChinaName').asString, adsDBObj.fieldbyname('TableDescribe').asString); adsDBObj.Next; end; end; adsDBObj.Free; end;destructor TDBMetaDataSet.Destroy; var i,count:Integer; begin count := length(FObjects); for i :=0 to count -1 do FObjects[i].Free; inherited Destroy; end;function TDBMetaDataSet.getObject(const objName:String):TDBObject; var i,count:Integer; begin count := length(FObjects); Result := nil; for i :=0 to count -1 do begin if FObjects[i].FTableName = uppercase(objName) then begin Result := FObjects[i]; exit; end; end; end;end.
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }uses
SysUtils,
Classes,
Forms,
Windows,
DPunit in '..\..\IC\AP88\Public\DPunit.pas' {DPDM: TDataModule},
unExport in 'unExport.pas',
Unit1 in 'Unit1.pas' {Form1},
IC_ErrorMessageUnit in '..\..\IC1\IC_ErrorMessageUnit.pas',
untIC_Public in '..\..\IC1\untIC_Public.pas',
untIC_LoggerDM in '..\..\IC1\untIC_LoggerDM.pas' {IC_LoggerDM: TDataModule},
untIC_Logger in '..\..\IC1\untIC_Logger.pas',
logconfig in '..\..\IC1\logconfig.pas',
SearchUnit in '..\..\IC1\SearchUnit.pas' {SearchForm},
uBase64Code in '..\..\IC1\uBase64Code.pas',
ModalFrmUnt in '..\..\IC1\ModalFrmUnt.pas' {FrmModal},
ICMFindCardUnt in '..\..\IC1\ICMFindCardUnt.pas' {ICMFindCardForm},
ICCardImpUnt in '..\..\IC1\ICCardImpUnt.pas',
DBMetaDataUnt in '..\..\IC1\DBMetaDataUnt.pas',
DBDataSetUnt in '..\..\IC1\DBDataSetUnt.pas',
AccountImpUnt in '..\..\IC1\AccountImpUnt.pas',
MarketAccountImpUnt in '..\..\IC1\MarketAccountImpUnt.pas',
AccountManagerImpUnt in '..\..\IC1\AccountManagerImpUnt.pas',
ICMUnit in '..\..\IC1\ICMUnit.pas',
ICM_untPublic in '..\..\IC1\ICM_untPublic.pas',
ICM_untMifareIICCard in '..\..\IC1\ICM_untMifareIICCard.PAS',
VendueConst in '..\..\IC1\VendueConst.pas',
md5 in '..\..\IC1\md5.pas',
Cl_crypt32 in '..\..\IC\AP88\Public\Cl_crypt32.pas';{$R *.res}Exports
LoadFrm;
var
GApplication: TApplication ;
GScreen: TScreen;procedure InitDll(dWseason: DWORD);
begin
case dWseason of
DLL_PROCESS_ATTACH:
begin
GApplication := Application;
GScreen := Screen;
end;
DLL_PROCESS_DETACH:
begin
Application := GApplication;
Screen := GScreen;
end;
end;
end;begin
DllProc := @InitDll;
InitDll(DLL_PROCESS_ATTACH);
end.
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; procedure LoadFrm(App: TApplication; Scr: TScreen); StdCall;
implementationuses Unit1,DPunit, DBMetaDataUnt;procedure LoadFrm(App: TApplication; Scr: TScreen );
var
LPtr: PLongint;
begin
if Form1 <> nil then Exit; Application := App;
Screen := Scr;
LPtr := @Application.MainForm;
LPtr^ := Longint(App.MainForm); if DPDM <> nil then
DPDM := TDPDM.Create(App.MainForm); DBMetaDataSet := TDBMetaDataSet.Create;
Form1 := TForm1.Create(App.MainForm);
Form1.Left := (App.MainForm.Width-Form1.Width) div 2 ;
Form1.Top := (App.MainForm.Height-Form1.Height) div 2 ;
Form1.Show;
end;end.
uses Classes, SysUtils, AdoDB, untIC_Public,QDialogs;type
TDBColumn = class(TObject)
private
FTableName:String;
FFieldName:String;
FChineseName:String;
FIsKey:Integer;
FIsRepeat:Integer;
FIsNull:Integer;
FFielddefault:String;
FType:String;
FLength:Integer;
FDisplayLength:Integer;
FIsReadOnly:Integer;
public
constructor Create(const pTableName:String;
const pFieldName:String; const pFieldChinaName:String;
const pIsKey:Integer;
const pIsRepeat:Integer;
const pIsNull:Integer;
const pfielddefault:String;
const pfileldtype:String;
const pLength:Integer;const pDisplayLength:Integer;
const pIsReadOnly:Integer);
published
property TableName:String read FTableName;
property FieldName:String read FFieldName;
property ChineseName:String read FChineseName;
property IsKey:Integer read FIsKey;
property IsRepeat:Integer read FIsRepeat;
property IsNull:Integer read FIsNull;
property Fielddefault:String read FFielddefault;
property ColumnType:String read FType;
property Length:Integer read FLength;
property DisplayLength:Integer read FDisplayLength;
property IsReadOnly:Integer read FIsReadOnly;
end;type
TDBObject = class(TObject)
private
FTableName:String;
FChineseName:String;
FTableDescription:String;
FColumns:array of TDBColumn;
function getCount:Integer;
public
function getColumn(const fieldName:String):TDBColumn;overload;
function getColumn(const index:Integer):TDBColumn;overload;
constructor Create(const tabName:String;const chName :String;const tabDescr:String);
destructor Destroy;override;
published
property TableName:String read FTableName;
property ChineseName:String read FChineseName;
property Description:String read FTableDescription;
property Count:Integer read getCount;
end;type
TDBMetaDataSet = class(TObject)
private
FObjects:array of TDBObject;
public
function getObject(const objName:String):TDBObject;
constructor Create;
destructor Destroy;override;
end;var
DBMetaDataSet:TDBMetaDataSet;
implementationconstructor TDBObject.Create(const tabName:String;const chName :String;const tabDescr:String);
var adsTemps:TADODataSet;
i,count:Integer;
begin
FTableName := uppercase(tabName);
FChineseName := chName;
if tabDescr = '' then
FTableDescription := tabName
else
FTableDescription := tabDescr;
adsTemps:=untIC_Public.RunDataSet('select FieldName, FieldChinaName, IsKey, IsRepeat, IsNull, fielddefault, type, Length, DisplayLength,IsReadOnly from DPColumns where UPPER(tablename)=UPPER('+quotedStr(tabName)+') order by FieldOrder');
count := adsTemps.RecordCount;
if count > 0 then
setLength(FColumns,count);
begin
for i := 0 to count -1 do
begin
FColumns[i]:=TDBColumn.Create(tabName,
adsTemps.fieldbyname('FieldName').asString,
adsTemps.fieldbyname('FieldChinaName').asString,
adsTemps.fieldbyname('IsKey').asInteger,
adsTemps.fieldbyname('IsRepeat').asInteger,
adsTemps.fieldbyname('IsNull').asInteger,
adsTemps.fieldbyname('fielddefault').asString,
adsTemps.fieldbyname('type').asString,
adsTemps.fieldbyname('Length').asInteger,
adsTemps.fieldbyname('DisplayLength').asInteger,
adsTemps.fieldbyname('IsReadOnly').asInteger); adsTemps.Next;
end;
end;
adsTemps.Free;
end;destructor TDBObject.Destroy;
var
i,count:Integer;
begin
count := length(FColumns);
for i :=0 to count -1 do
FColumns[i].Free;
inherited Destroy;
end;function TDBObject.getCount:Integer;
begin
Result := Length(FColumns);
end;function TDBObject.getColumn(const index:Integer):TDBColumn;
begin
if (index<0) or (index >= Length(FColumns)) then
Result := nil
else
Result := FColumns[index];
end;function TDBObject.getColumn(const fieldName:String):TDBColumn;
var
i,count:Integer;
begin
count := length(FColumns);
Result := nil;
for i :=0 to count -1 do
begin
if FColumns[i].FFieldName = uppercase(fieldName) then
begin
Result := FColumns[i];
exit;
end;
end;
end;constructor TDBColumn.Create(const pTableName:String;
const pFieldName:String; const pFieldChinaName:String;
const pIsKey:Integer;
const pIsRepeat:Integer;
const pIsNull:Integer;
const pfielddefault:String;
const pfileldtype:String;
const pLength:Integer;const pDisplayLength:Integer;
const pIsReadOnly:Integer);
begin
FTableName:=uppercase(pTableName);
FFieldName:=uppercase(pFieldName);
if pFieldChinaName = '' then
FChineseName:= FFieldName
else
FChineseName:=pFieldChinaName;
FIsKey:= pIsKey;
FIsRepeat:=pIsRepeat;
FIsNull:=pIsNull;
FFielddefault:=pfielddefault;
FType:=pfileldtype;
FLength:=pLength;
FDisplayLength:=pDisplayLength;
FIsReadOnly := pIsReadOnly;
end;constructor TDBMetaDataSet.Create;
var
adsDBObj:TADODataSet;
i,count:Integer;
begin
adsDBObj:=untIC_Public.RunDataSet('select TableName,TableChinaName,TableDescribe from DPObjects');
count := adsDBObj.RecordCount;
if count > 0 then
begin
setLength(FObjects,count);
for i := 0 to count -1 do
begin
FObjects[i]:=TDBObject.Create(adsDBObj.fieldbyname('TableName').asString,
adsDBObj.fieldbyname('TableChinaName').asString,
adsDBObj.fieldbyname('TableDescribe').asString);
adsDBObj.Next;
end;
end;
adsDBObj.Free;
end;destructor TDBMetaDataSet.Destroy;
var
i,count:Integer;
begin
count := length(FObjects);
for i :=0 to count -1 do
FObjects[i].Free;
inherited Destroy;
end;function TDBMetaDataSet.getObject(const objName:String):TDBObject;
var
i,count:Integer;
begin
count := length(FObjects);
Result := nil;
for i :=0 to count -1 do
begin
if FObjects[i].FTableName = uppercase(objName) then
begin
Result := FObjects[i];
exit;
end;
end;
end;end.