将 PowerBasic 的 DLL 调用转换为 Delphi

Translate a DLL call from PowerBasic to Delphi

我想从 Delphi 调用 SPSS 'backend'。有一个我可以使用的 DLL(似乎):SPSSio64.DLL。但是我找不到接口定义。

我找到的是 PowerBasic 中的示例:

Read and write SPSS sav files

DECLARE FUNCTION spssOpenRead LIB "spssio32.dll" ALIAS "spssOpenRead@8" (BYVAL fileName AS STRING, BYREF hHandle AS LONG) AS LONG
DECLARE FUNCTION spssCloseRead LIB "spssio32.dll" ALIAS "spssCloseRead@4" (BYVAL hHandle AS LONG) AS LONG

因为我只需要读取和写入文件的函数(所有处理都将通过该文件中的语法完成),我认为这个例子可能足以推断出如何从 Delphi.

所以问题是:这些声明如何在 Delphi(64 位)中?

基于 SPSS 14.0 for Windows Developer's Guide, and PowerBasic documentation,尝试这样的操作:

32 位:

// spssio32.dll exports both 'spssOpenRead' and 'spssOpenRead@8', which are the same function...
function spssOpenRead(filename: PAnsiChar; var hHandle: Integer): Integer; stdcall; external 'spssio32.dll' {name 'spssOpenRead@8'};

// spssio32.dll exports both 'spssCloseRead' and 'spssCloseRead@4', which are the same function...
function spssCloseRead(hHandle: Integer): Integer; stdcall; external 'spssio32.dll' {name 'spssCloseRead@4'};

64 位:

// I can't find a copy of spssio64.dll to download, so I can't verify the exported names. Adjust if needed..

function spssOpenRead(filename: PAnsiChar; var hHandle: Integer): Integer; stdcall; external 'spssio64.dll' {name 'spssOpenRead@16'};

function spssCloseRead(hHandle: Integer): Integer; stdcall; external 'spssio64.dll' {name 'spssCloseRead@8'};

郑重声明,这有效:

function LoadDLL(DLLname : string) : Uint64;
var
  em : TArithmeticExceptionMask;
begin
  em:=GetExceptionmask;
  SetExceptionmask(em+[exInvalidOp,exZeroDivide,exOverflow,exUnderflow]);
  result:=LoadLibrary(PwideChar(DLLname));
  SetExceptionmask(em);
end;

function RunSPSSio(filename : string; instructions : Tinstructions) : boolean;
// This will only read SAV files, not SPS files !
type
  TspssOpenRead             = function (filename: PAnsiChar; var hHandle: Uint64): Integer;
  TspssCloseRead            = function(hHandle: Uint64): Integer;
  TspssGetInterfaceEncoding = function(hHandle : Uint64): Integer;
  TspssSetInterfaceEncoding = function(encoding : integer; hHandle : Uint64): Integer;
const
  SPSS_ENCODING_UTF8     = 1;
var
  p                      : integer;
  spssOpenRead           : TspssOpenRead;
  spssCloseRead          : TspssCloseRead;
  spssGetIFencoding      : TspssGetInterfaceEncoding;
  spssSetIFencoding      : TspssSetInterfaceEncoding;
  DLLhandle              : Uint64;
  fileref                : PANSIchar;
begin
  result:=false;
  DLLhandle:=LoadDLL('C:\SPSS\spssio64.dll'); // hardcoded
  if DLLhandle=0
     then begin p:=GetLastError();
                report('DLL load error '+IntToStr(p));
                exit;
          end;
  try
    @SPSSopenRead:=getProcAddress(DLLhandle,'spssOpenRead');
    @SPSScloseRead:=getProcAddress(DLLhandle,'spssCloseRead');

    @SPSSsetIFencoding:=getProcAddress(DLLhandle,'spssSetInterfaceEncoding');
    SPSSsetIFencoding(SPSS_ENCODING_UTF8,DLLhandle);

    fileref:=PANSIchar(ANSIstring(filename));
    p:=SPSSopenRead(fileref,DLLhandle);
    if p<>0
       then report('*** SPSSio error '+IntToStr(p))
       else begin // SPSS database interactions here
                  result:=SPSScloseRead(DLLhandle)=0;
            end;
  finally
    freeLibrary(DLLhandle);
  end;
end;