【问题标题】:Translate a DLL call from PowerBasic to Delphi将 DLL 调用从 PowerBasic 转换为 Delphi
【发布时间】:2017-09-28 18:46:11
【问题描述】:

我想从 Delphi 调用 SPSS“后端”。有一个我可以使用的 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 位)中如何?

【问题讨论】:

  • 这都有记录。尝试自己做。
  • 请注意,您要使用spssio64.dll,但示例适用于spssio32.dll。
  • 当您是专家时一定很容易。当你不是,并且你不知道从哪里开始或如何询问时,挫折感就会引诱。鲁迪:谢谢;大卫:指针会很棒。
  • 我建议你做一些研究并阅读一些文档。感觉好像您只想获得代码。这将如何帮助您学习。这个问题对其他人有什么价值。您现在有一个答案,它不提供教学或解释,只提供代码。这让我很沮丧。没有人通过盲目复制代码成为专家。是的,当您是专家时,这很容易。你不想成为专家吗?
  • 正确。我是专家,但在完全不同的领域。当您需要更换正在建造的核电站后门的锁时,无需学习 - 只需找一个知道如何更换锁的人。我总是乐于帮助别人。我们不应该进行这样的讨论。

标签: delphi dll spss


【解决方案1】:

基于SPSS 14.0 for Windows Developer's GuidePowerBasic 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'};

【讨论】:

  • IBM 非常乐意发送 SPSSio64 的完整文档。名称是正确的。调用有效。
【解决方案2】:

为了记录,这是有效的:

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;

【讨论】:

    猜你喜欢
    • 2015-07-28
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多