如何从64位客户端应用程序枚举MSSQL服务器?

Tob*_*ves 4 sql-server delphi

我正在寻找一种从64位Delphi应用程序枚举本地网络上的MS SQL Server的方法.到目前为止我在32位上使用的方法工作正常,但包含不能在32位编译的汇编代码.我似乎找不到从64位客户端枚举服务器的方法.

我无法编译的代码是这样的:

function PtCreateADOObject(const ClassID: TGUID): IUnknown;
var
  Status: HResult;
  FPUControlWord: Word;
begin
  asm
    FNSTCW FPUControlWord
  end;
  Status := CoCreateInstance(
              CLASS_Recordset,
              nil,
              CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER,
              IUnknown,
              Result);
  asm
    FNCLEX
    FLDCW FPUControlWord
  end;
  OleCheck(Status);
end;
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 8

导致您麻烦的代码只是存储和恢复浮点控制状态.你可以用跨平台的方式编写它(好吧,支持x86和x64),如下所示:

type
  TFPControlState = {$IFDEF CPUX86}Word{$ENDIF}{$IFDEF CPUX64}UInt32{$ENDIF};

function GetFPControlState: TFPControlState;
begin
  {$IFDEF CPUX86}
  Result := Get8087CW;
  {$ENDIF}
  {$IFDEF CPUX64}
  Result := GetMXCSR;
  {$ENDIF}
end;

procedure SetFPControlState(const Value: TFPControlState);
begin
  {$IFDEF CPUX86}
  Set8087CW(Value);
  {$ENDIF}
  {$IFDEF CPUX64}
  SetMXCSR(Value);
  {$ENDIF}
end;
Run Code Online (Sandbox Code Playgroud)

这抽象出32位代码使用具有16位控制状态的8087单元的事实,64位代码使用具有32位控制状态的SSE单元.

现在您的功能变为:

function PtCreateADOObject(const ClassID: TGUID): IUnknown;
var
  Status: HResult;
  FPControlState: TFPControlState;
begin
  FPControlState := GetFPControlState;
  Status := CoCreateInstance(
    CLASS_Recordset,
    nil,
    CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER,
    IUnknown,
    Result
  );
  SetFPControlState(FPControlState);
  OleCheck(Status);
end;
Run Code Online (Sandbox Code Playgroud)

这种方法有很多好处.最清楚的是:

  1. 您完全避免使用汇编程序代码.
  2. 您可以使用标准RTL单元来操作浮点控制状态.
  3. 您将条件代码限制在低级例程中.高级例程可以保持对该细节的无知,并且您可以在高级别的不同位置重用此方法,而不会使用条件进行污染.