是否可以从 Forth 调用 Windows API?

Is it possible to call the Windows API from Forth?

在 C/C++ 中,Windows 可执行文件链接到导入包含 Windows API 过程的 DLL 文件的静态库。

但是我们如何从 Forth 代码(例如 GForth)访问这些过程?有可能吗?

我知道 Win32Forth 可以做 Win32 的事情,但我感兴趣的是如何(以及是否)在缺少此功能的 Forth 实现中做到这一点(但 运行在目标 OS 上并且有可能在一定程度上与其互动)。

我目前想到的是加载有问题的 DLL 文件并以某种方式定位要执行的过程的地址 - 但是然后,执行 如何? (我只知道 Windows API 使用 stdcall 惯例)。我们如何找到没有 C 头文件的过程? (我对 Forth 很陌生,对 C++ 不太陌生。如果我的想法是胡说八道,请多多包涵)。

是的,您可以根据其文档在 Gforth 中执行此操作。最大的问题是处理回调,Windows API 非常依赖回调。有一个不受支持的包可以处理这个问题,请参阅 5.25.6 Callbacks。我自己没有在 Gforth 中尝试过,但是文档看起来足够了。

您可能还想查看 MPE's VFXForth。来自他们的网站:

Windows API Access

VFX Forth can access all the standard Windows API calls, as well as functions in any other DLLs. The function interface allows API calls to be defined by cut and paste from other language reference manuals, for example:

EXTERN: int PASCAL CreateDialogIndirectParam( HINSTANCE, void *,HWND, WNDPROC, LPARAM );
EXTERN: int PASCAL SetWindowText( HANDLE, LPSTR );
EXTERN: HANDLE PASCAL GetDlgItem( HANDLE, int );

这在 VFX Forth for Windows 页面下方一点。

因为我在 Mac 和 Linux 上做我的 Forth,我无法通过 Windows 为 Gforth 提供更多细节,抱歉。

一般情况下,要在某些 Forth 系统中实现动态加载库的外部函数接口 (FFI) 作为扩展(即不更改源代码和重新编译),我们需要 dlopendlsym 函数、Forth 汇编程序,以及对 Forth 系统组织和 ABI 的深入了解。 有时即使没有汇编程序也可以完成。例如,虽然 SP-Forth has FFI, foreign calls were also implemented 在纯 Forth 中是本机代码生成以及 return 堆栈与本机硬件堆栈联合的结果。

关于Gforth,好像是0.7.9版本的(见releases) it doesn't have FFI for stdcall calling convention out of the box (it supports cdecl only), although it has dlopen and dlsym, and an assembler。所以stdcall实现FFI应该是可行的。

Gforth 0.7.9 提供 Windows API Swig 从 Windows 头文件生成的调用。 C 接口使用由 C 编译器编译的包装库,将参数从 Forth 堆栈传递给系统函数;由于 C 编译器理解 stdcall,并且头文件将 Windows API 声明为 stdcall,因此 "just works".

由于所有预生成的 C 绑定都位于目录 "unix" 中(由于历史原因),include unix/win32.fs 为您提供了 Windows API 的 win32 部分。

事件循环中的回调仍然是一个问题,因为 Gforth 是一个 Cygwin 程序,而 Cygwin 有其特殊的事件循环任务...但我希望这个问题能够得到解决。