0

如果我们从不同的语言调用它的函数,那么一种语言会在我们需要语言绑定的编译库上留下什么标记?

目标代码对我来说看起来“无语言”。

在 Linux 环境中用 c 语言学习 OpenGL 时,我有跨语言绑定。

4

3 回答 3

3

绑定为应用程序呈现数据和与数据交互提供了一种简单且一致的方式。

来源:您问题下的标签

于 2013-10-11T11:08:19.173 回答
2

我猜你要么很年轻,要么已经十多年没有编程了。

目标代码看起来应该与语言无关,但这不是由于历史原因。回到 1970 年代和 1980 年代,在 Intel 80x86 和 Motorola 680x0 CPU 上,函数调用参数在堆栈上传递。在“Pascal”约定中,参数的数量是固定的,并且被调用的函数代码在返回之前将它们从堆栈中删除。在“C”约定中,参数的数量是可变的(例如 printf),因此调用代码必须在函数返回时删除它们。每个函数调用需要额外的 2 个字节,这在今天不算什么,但在当时 PC 只配备 128K 左右的 RAM 时就很重要了。所以微软选择为 Windows API 使用 Pascal 调用约定,即使它是用 C 编写的。如果你的目标代码错误地调用了具有 C 约定的 Windows 函数,kaboom。

从 1990 年代开始,操作系统作者意识到这很愚蠢,并开始将标准调用约定强加给每个人。C 约定可以处理这两种情况,因此它被到处使用。随着迁移到 MacOS X、64 位 Windows 和 ARM;我们终于得到了无语言的目标代码。

现在,OpenGL 被设计为从 C 和 Fortran 中使用。(在 1990 年代它仍然是科学计算和可视化的重要语言。)两种语言都有整数、浮点数和各种大小的整数/浮点数数组。C 有结构,但 Fortran 没有,我怀疑这是 OpenGL API 从不使用任何结构的主要原因。C 和 Fortran 之间的 2D 或更高维数组的内存布局也存在差异,再次注意 OpenGL API 从不指定 2D 数组,仅指定 1D。

AC API 适用于大多数语言。这部分是因为 C 是“便携式汇编程序”,几乎可以在任何 CPU 和操作系统上运行。这也是因为大多数其他常用编程语言要么是 C(C++、Objective-C)的超集,要么是用 C 本身(Python、Perl、Ruby)实现的,因此可以合理地轻松调用 OpenGL C API。

Java 和 C# 的问题更多,因为它们定义了自己的目标代码,可以说是对内存访问进行了更严格的控制。C/OpenGL 的“这里是一个指向内存块的指针,随心所欲地使用它”的概念破坏了 JVM/CLR 的安全模型。所以你最终不得不使用 Java NIOByteBuffer 东西,而不仅仅是传递数组。

其中很多也归结为语言绑定设计师的技能。例如,Mike Fletcher 的 Python-OpenGL 是一种非常好的绑定。所有的函数和常量都具有完全相同的名称,所以很多代码可以从 C 语言复制并粘贴到 Python 中。Python 没有直接的 C 样式数组,但语言绑定会默默地将您作为“数组”传递的任何 Python 序列/元组翻译成底层 C 格式。对于 Python 程序员来说,这感觉很自然,并且仍然公开了 OpenGL 的全部功能。

举一个不好的例子,JOGL 是个麻烦事。没有从 Java 数组到 C 的自动转换,因此您必须自己使用 NIOByteBuffers。这很烦人,实际上使用 glBegin..glEnd 块更容易。并且额外的数组偏移参数被添加到许多 OpenGL 函数中,因此您的代码看起来不再与 C/C++ 相同,并且您在函数调用结束时浪费了大量时间粘贴 ,0。其中一些是由于之前提到的 JVM 造成的,但其中很多只是(我怀疑)从未真正自己编写过很多 OpenGL 的人的糟糕设计。

对一个模糊问题的冗长而漫不经心的回答。

于 2013-10-14T04:00:19.497 回答
1

好吧,您所要做的就是想想 C 和 C++ 中的无数调用约定。为了防止发生严重的事故,编译器会根据调用约定修改函数名称,这样您就不会意外地使用约定调用stdcall函数。fastcall每种语言都有自己的一组多余的细节,像这样的独立于语言的 API 永远不必负担自己的负担。语言绑定充当适配器/桥梁,将特定语言的内容与标准化 API 分开,在必要时填补空白。

OpenGL API 通常以单一语言 (C) 实现,用其他语言编写的程序通过语言绑定与系统的实现接口。OpenGL 为 GLSL 使用以 null 结尾的 ASCII 字符串,并且有许多使用指针的函数,这对于设计为用 C 实现的 API 非常有意义。在 Java 中,字符串不是以 null 结尾的,它们是 UTF-16 编码的; 你可以看到为什么需要一座桥。Java GL 绑定负责字符串转换和类似更改glVertexPointer (...)的函数,以适应 Java “指向”连续内存块的条件。

于 2013-10-12T12:53:38.063 回答