3

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

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

我知道有 Win32Forth 能够做 Win32 的东西,但我很感兴趣如何(以及是否)这可以在缺少此功能的 Forth 实现中完成(但确实在目标操作系统上运行并且可能能够交互在一定程度上使用它)。

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

4

3 回答 3

4

一般情况下,要在某些 Forth 系统中为动态加载的库实现外部函数接口 (FFI) 作为扩展(即,不更改源代码和重新编译),我们需要dlopenanddlsym函数、Forth 汇编器以及对 Forth 系统的深入了解组织和 ABI。有时即使没有汇编程序也可以完成。例如,尽管SP-Forth具有 FFI,但由于本地代码生成以及返回堆栈与本地硬件堆栈的联合,外部调用也在纯 Forth 中实现。

关于 Gforth,似乎在 0.7.9 版本(请参阅发布)中,它没有开箱即用的 stdcall 调用约定的 FFI(它仅支持 cdecl),尽管它具有dlopen 和 dlsym以及一个 assembler。因此,为 stdcall 实现 FFI 应该是可行的。

于 2015-09-07T23:37:24.880 回答
3

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

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

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

于 2016-11-05T23:30:37.220 回答
3

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

您可能还想查看MPE 的 VFXForth。从他们的网站:

Windows API 访问

VFX Forth 可以访问所有标准的 Windows API 调用,以及任何其他 DLL 中的函数。该函数接口允许通过从其他语言参考手册中剪切和粘贴来定义 API 调用,例如:

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 提供更多细节,抱歉。

于 2015-09-07T14:15:55.577 回答