gpt4 book ai didi

sql-server - 通过 Delphi DLL 连接到 SQL 时 Delphi 10.2 Tokyo 程序抛出 216 错误

转载 作者:行者123 更新时间:2023-12-03 08:20:12 32 4
gpt4 key购买 nike

几年来,我们已经断断续续地报告了这个错误,现在我必须花一些时间来解决它。

其他来源也提到过几次:

https://forums.embarcadero.com/thread.jspa?threadID=112713

https://forums.devart.com/viewtopic.php?t=37398

https://forums.devart.com/viewtopic.php?f=10&t=16520

我已经向 DevArt 开了一张票,给了他们我的测试程序和 dll 的副本,但他们非常正确地回答说即使没有 DevArt 驱动程序也会出现问题,我已经确认使用 10.2 Tokyo Enterprise 提供的标准 MSSQL 驱动程序并且没有 DevArt驱动程序正在安装,在所有。

DLL 有一个功能:

exports
CheckConnection;

这是 DLL 中的单元代码:
unit Unit7;

interface

uses
System.SysUtils, Data.SqlExpr, Data.DBXMSSQL;

function CheckConnection(const ServerName, DatabaseName, UserName, Password: PAnsiChar): Boolean; stdCall export;

implementation

function CheckConnection(const ServerName, DatabaseName, UserName, Password: PAnsiChar): Boolean; stdCall export;
var
SQLConnection: TSQLConnection;
begin
SQLConnection := TSQLConnection.Create(nil);

try
SQLConnection.DriverName := 'MSSQL';
SQLConnection.LibraryName := 'dbxmss.dll';
SQLConnection.VendorLib := 'sqlncli10.dll';
SQLConnection.GetDriverFunc := 'getSQLDriverMSSQL';

SQLConnection.Params.Values['HostName'] := ServerName;
SQLConnection.Params.Values['Database'] := DatabaseName;
SQLConnection.Params.Values['User_Name'] := UserName;
SQLConnection.Params.Values['Password'] := Password;

SQLConnection.LoginPrompt := False;
SQLConnection.Open;

Result := SQLConnection.Connected;
finally
SQLConnection.Close;
FreeAndNil(SQLConnection);
end;
end;

end.

此实现行允许从主程序使用 DLL 函数:
function CheckConnection(const Server, Database, User, Password: PAnsiChar): Boolean; stdCall; external 'Project3.dll';

这是调用 DLL 的按钮单击事件的代码:
procedure TForm8.Button1Click(Sender: TObject);
var
Server, Database, User, Password: AnsiString;
begin
Server := Edit1.Text;
Database := Edit2.Text;
User := Edit3.Text;
Password := Edit4.Text;

if CheckConnection(@Server[1], @Database[1], @User[1], @Password[1]) then
Label1.Caption := 'DLL connected OK'
else
Label1.Caption := 'DLL did not connect';
end;

问题源于 TDBXDriverRegistry.CloseAllDrivers 中的循环,它为安装/使用的每个 dbExpress 驱动程序调用 TDBXDriverRegistry.DBXDriverRegistry.FreeDriver。

当调用 FreeDriver 时,执行线程会转到这个方法:
destructor TDBXDynalinkDriver.Destroy;
begin
if FMethodTable <> nil then
FMethodTable.FDBXBase_Close(FDriverHandle);
FDriverHandle := nil;
FreeAndNil(FMethodTable);
inherited Destroy;
end;

它是 FMethodTable.FDBXBase_Close(FDriverHandle); 引发访问冲突的行,并且由于它未被捕获,因此会导致调用程序中发生 216 错误。

此调用仅在最后一个驱动程序被释放时失败,并且仅在我们实际打开 TSQLConnection 时才会失败。

鉴于我在 DLL 中使用 DevExpress VCL 组件的经验,您需要调用 dxInitialize 和 dxFinalize 才能正确使用 GDIPlus,我只能认为需要在 DLL 中或从调用程序中完成某些操作,在为了解决这个错误,但我无法弄清楚那可能是什么,因此这个问题。

最佳答案

我收到了 Embarcadero 的回复,说我们应该添加 AutoUnloadDriver=真到参数

"avoid finalization order issues."



我们可以添加它并做出任何改变的唯一地方(因为它解决了 216 错误)是在 [MSSQL] dbxdrivers.ini 文件的 block 。

http://edn.embarcadero.com/article/39392/

DevArt 通知我,他们现在已在其 中添加了对 AutoUnloadDriver 参数的支持。 SQL Server 的 dbExpress 驱动程序 .他们给我发了一个包含此修复程序的夜间版本,因为它还没有在他们的公开发布版本中。

使用应用程序安装文件夹中的 dbxdrivers.ini 文件,并使用 AutoUnloadDriver=真参数添加到 [MSSQL][DevArtSQLServer]在关闭使用 DLL 连接到 SQL Server 的应用程序时,我们不再收到任何 216 错误。

关于sql-server - 通过 Delphi DLL 连接到 SQL 时 Delphi 10.2 Tokyo 程序抛出 216 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55448287/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com