调用dll后出息'Invalid pointer operation'错误,如何解决????
library GetTmpTable;uses
ShareMem,
Windows,
SysUtils,
Classes,ComObj, ActiveX,ADODB,
xUtils;var
ADOCon : TADOConnection;
ADOQry : TADOQuery;
ADOConStr, ADOQuerySQLStr: String;{$R *.res}
{exports
DataOpen;
exports
DataClose;
}
procedure DataDLLHandler(Reason:Integer);
begin
case Reason of
DLL_PROCESS_ATTACH:
begin
CoInitialize(nil);
ADOCon := TADOConnection.Create(nil);
ADOQry := TADOQuery.Create(nil);
end;
DLL_PROCESS_DETACH:;
DLL_THREAD_ATTACH:;
DLL_THREAD_DETACH:;
end;
end;procedure DataFreeProc; stdcall;
begin
ADOCon.Close;
if ADOQry <> nil then
begin
ADOQry.Free;
ADOQry := Nil;
end;
if AdoCon <> nil then
begin
AdoCon.Free;
AdoCon := nil;
end;
CoUnInitialize();
end;//赋连接字符串
procedure SetADOConStr(vADOConStr:pchar);stdcall;
begin
ADOConStr := strpas(vADOConStr);
end;function DataOpen:BOOL; StdCall;//打开数据库
begin
try ADOCon.Close;
ADOCon.CommandTimeout:=30000;
ADOCon.ConnectionString:=AdoConStr;
AdoQry.Connection:=AdoCon;
ADOCon.Open;MsgBox('ok');
Result:=true; except
Result:=false;
end;
end;exports
DataFreeProc,
SetADOConStr,
DataOpen;
// SetADOQuerySQLStr,
// ADOQueryExecSQL;
begin
DLLProc := @DataDLLHandler;
DataDLLHandler(DLL_PROCESS_ATTACH);
end.//调用代码unit Unit1;interfaceuses
ShareMem,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, xUtils, XPMan, DB, ADODB;type //在此创建一个函数类
TDataOpen = function:BOOL;StdCall;
TDataFreeProc = procedure;StdCall;
TSetADOConStr = procedure (S:pchar);StdCall;
EDLLLoadError = class(Exception);//同时分创建一个出错记录类 TForm1 = class(TForm)
lbl1: TLabel;
xpmnfst1: TXPManifest;
edt1: TEdit;
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
var //按钮的调用事件:调用过程 LibHandle : THandle;
DataOpen : TDataOpen;
DataFreeProc : TDataFreeProc;
SetADOConStr : tSetADOConStr;
s:string;
begin
s:=edt1.Text;
LibHandle:=LoadLibrary('C:\Documents and Settings\mazheng\桌面\软件\text\调用Dll\GetTmpTable.dll');
try
if LibHandle = 0 then
raise EDLLLoadError.Create('无法成功装入GetTmpTable.dll');
DataOpen := GetProcAddress(LibHandle, 'DataOpen');
DataFreeProc := GetProcAddress(LibHandle, 'DataFreeProc');
SetADOConStr := GetProcAddress(LibHandle, 'SetADOConStr'); SetADOConStr(pchar(s)); if DataOpen then
DataFreeProc; finally
FreeLibrary(LibHandle); // Unload the DLL.
end;end;end.
library GetTmpTable;uses
ShareMem,
Windows,
SysUtils,
Classes,ComObj, ActiveX,ADODB,
xUtils;var
ADOCon : TADOConnection;
ADOQry : TADOQuery;
ADOConStr, ADOQuerySQLStr: String;{$R *.res}
{exports
DataOpen;
exports
DataClose;
}
procedure DataDLLHandler(Reason:Integer);
begin
case Reason of
DLL_PROCESS_ATTACH:
begin
CoInitialize(nil);
ADOCon := TADOConnection.Create(nil);
ADOQry := TADOQuery.Create(nil);
end;
DLL_PROCESS_DETACH:;
DLL_THREAD_ATTACH:;
DLL_THREAD_DETACH:;
end;
end;procedure DataFreeProc; stdcall;
begin
ADOCon.Close;
if ADOQry <> nil then
begin
ADOQry.Free;
ADOQry := Nil;
end;
if AdoCon <> nil then
begin
AdoCon.Free;
AdoCon := nil;
end;
CoUnInitialize();
end;//赋连接字符串
procedure SetADOConStr(vADOConStr:pchar);stdcall;
begin
ADOConStr := strpas(vADOConStr);
end;function DataOpen:BOOL; StdCall;//打开数据库
begin
try ADOCon.Close;
ADOCon.CommandTimeout:=30000;
ADOCon.ConnectionString:=AdoConStr;
AdoQry.Connection:=AdoCon;
ADOCon.Open;MsgBox('ok');
Result:=true; except
Result:=false;
end;
end;exports
DataFreeProc,
SetADOConStr,
DataOpen;
// SetADOQuerySQLStr,
// ADOQueryExecSQL;
begin
DLLProc := @DataDLLHandler;
DataDLLHandler(DLL_PROCESS_ATTACH);
end.//调用代码unit Unit1;interfaceuses
ShareMem,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, xUtils, XPMan, DB, ADODB;type //在此创建一个函数类
TDataOpen = function:BOOL;StdCall;
TDataFreeProc = procedure;StdCall;
TSetADOConStr = procedure (S:pchar);StdCall;
EDLLLoadError = class(Exception);//同时分创建一个出错记录类 TForm1 = class(TForm)
lbl1: TLabel;
xpmnfst1: TXPManifest;
edt1: TEdit;
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
var //按钮的调用事件:调用过程 LibHandle : THandle;
DataOpen : TDataOpen;
DataFreeProc : TDataFreeProc;
SetADOConStr : tSetADOConStr;
s:string;
begin
s:=edt1.Text;
LibHandle:=LoadLibrary('C:\Documents and Settings\mazheng\桌面\软件\text\调用Dll\GetTmpTable.dll');
try
if LibHandle = 0 then
raise EDLLLoadError.Create('无法成功装入GetTmpTable.dll');
DataOpen := GetProcAddress(LibHandle, 'DataOpen');
DataFreeProc := GetProcAddress(LibHandle, 'DataFreeProc');
SetADOConStr := GetProcAddress(LibHandle, 'SetADOConStr'); SetADOConStr(pchar(s)); if DataOpen then
DataFreeProc; finally
FreeLibrary(LibHandle); // Unload the DLL.
end;end;end.
procedure TForm1.btn1Click(Sender: TObject);
var //按钮的调用事件:调用过程 LibHandle : THandle;
DataOpen : TDataOpen;
DataFreeProc : TDataFreeProc;
SetADOConStr : tSetADOConStr;
s:string;
begin
s:=edt1.Text;
LibHandle:=LoadLibrary('C:\Documents and Settings\mazheng\桌面\软件\text\调用Dll\GetTmpTable.dll');
try
if LibHandle = 0 then
raise EDLLLoadError.Create('无法成功装入GetTmpTable.dll'); SetADOConStr(pchar(s));
DataOpen := GetProcAddress(LibHandle, 'DataOpen');
DataFreeProc := GetProcAddress(LibHandle, 'DataFreeProc');
SetADOConStr := GetProcAddress(LibHandle, 'SetADOConStr');
if DataOpen then
DataFreeProc; finally
FreeLibrary(LibHandle); // Unload the DLL.
end;end;
CoInitialize(nil);
ADOCon := TADOConnection.Create(nil);
ADOQry := TADOQuery.Create(nil);
放在一個單獨的函數裏執行。先調用這個函數。
procedure CreateDBControl;
begin
CoInitialize(nil);
ADOCon := TADOConnection.Create(nil);
ADOQry := TADOQuery.Create(nil);
end;
先調用這個過程,再執行其它的過程。還有如樓上所說的。調用程序與DLL都要增加 sharemem, 發布時帶上 borlandMM.DLL
2.潜在问题
其它没有问题!procedure DataDLLHandler(Reason:Integer);
begin
case Reason of
DLL_PROCESS_ATTACH:
begin
CoInitialize(nil);
ADOCon := TADOConnection.Create(nil);
ADOQry := TADOQuery.Create(nil);
end;
DLL_PROCESS_DETACH: CoUnInitialize() ;//最好在这里退出COM环境 DLL_THREAD_ATTACH:;
DLL_THREAD_DETACH:;
end;
end;
//DLLprocedure SetADOConStr(vADOConStr:string);stdcall;
begin
ADOConStr := vADOConStr;
end;//project1var
s:string;
begin
s:=edt1.Text;
SetADOConStr(s);
end;