如何组合不同的编程语言
我不是在询问何时链接不同的编程语言。
这是一个相当普遍的问题,但我个人是在 Linux 上工作的。
我想了解的是不同的编程语言可以实现的过程 结合起来,我发现了一篇关于结合C/C++/Fortran的好文章: http://www-h.eng.cam.ac .uk/help/tpl/languages/mixinglanguages.html。
据我了解,大多数编译器执行两个阶段:
将语言文件翻译成包含机器代码但仍然包含的目标文件 包含一些符号(可能是函数名?)
将目标文件链接在一起,仅在这个阶段链接器检查函数 目标文件中的函数是可调用的。
我认为组合不同语言的问题是名称修改,这意味着 当函数转换为目标代码时,函数的名称会发生变化。
问题是:
您不能以某种方式提前发现损坏的函数名称,然后在编程语言中显式指定它们,或者更好的是,没有已经有这样做的软件吗?
我不完全理解动态库是如何链接的,但可以不同的语言 通过程序与动态库交互的相同方法进行交互?
ps 主要目的是调用用另一种语言编写的函数。
I'm not asking about WHEN to link different programming langauges.
This is quite a general question but I'm personally working on Linux.
What I want to understand is the process by which different programming languages can be
combined, I found a good article on combining C/C++/Fortran:
http://www-h.eng.cam.ac.uk/help/tpl/languages/mixinglanguages.html.
From what I understand most compilers perform two stages:
Translating the language files into object files which contain machine code but still
contain some symbols (possibly function names?)Linking the object files together, only at this stage the Linker checks that the functions
in the object files are callable.
I think that the problem with combining different languages is name mangling which means
that the names of the functions are changed when they are turned into object code.
The questions are:
Can't you somehow discover the mangled function names beforehand and than specify them explicitly in the programming language or better off, isn't there a software that already does that?
I don't understand completely how dynamic libraries are linked but can different languages
interact by the same method that programs interact with dynamic libraries?
p.s The main intent is to call functions written in another language.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
将不同目标文件链接在一起的问题通常归结为子例程调用约定。基本上,当您调用位于另一个目标文件中的例程时,编译器必须知道另一个目标文件将在内部为其例程命名什么,如何传递其所有参数,以及什么(如果有)设置和清理代码例行公事将需要。所有这些内容通常都在调用约定的标题下分组在一起。
每个编译器都有自己喜欢用于子例程的调用约定。注意我说的是“编译器”,而不是语言。 Linux 中的 C 调用约定与 Windows 上的 C 调用约定不同。
因此,当您混合使用语言时,您需要某种方法来告诉编译器调用或被调用的子例程使用另一种语言的调用约定。 C 的约定是一种流行的“通用语言”,因为几乎每个平台都有 C 编译器。然而,某些平台(例如:Windows)有多种流行的调用约定。
现在我们问您在评论中提出的问题:
答案是,“不,不是”。某些语言确实定义了使用特定其他语言的调用约定的方法。例如,C++ 允许您在声明上放置
extern "C"
来告诉编译器相关声明使用 C 调用约定。 Ada 通过 pragma Convention (X,...) 完成同样的事情,其中 X 是约定名称。C
、Fortran
和Cobol
由语言定义,但支持任何其他内容(例如:Windows 的Stdcall
) 是实现定义的。但是,如果您有两种语言,其编译器编写者从未想到过对方,那么您别无选择,只能告诉两者使用他们都知道的第三种约定(通常是 C 的约定)。例如,要使标准 C++ 和 Ada 进行互操作,您需要让服务器代码使用 C 约定导出其例程,并告诉客户端代码它正在调用的例程正在使用 C 约定。
The issue with linking different object files together generally comes down to subroutine calling conventions. Basically, when you make a call to a routine located in another object file, your compiler will have to know what that other object file will name its routine internally, how to pass all its parameters, and what (if any) setup and cleanup code the routine will require. All this stuff is generally grouped together under the heading of calling conventions.
Each compiler has its own calling conventions it likes to use for subroutines. Note I said "compiler", not language. The C calling convention in Linux is different than the C calling convention on Windows.
So when you mix languages, you need some way to tell the compiler for either the calling or the called subroutine to use the other language's calling convention. C's convention is a popular one to use as sort of a "lingua franca", as just about every platform has a C compiler. However some platforms (eg: Windows) have multiple popular calling conventions.
So now we ask the question you asked in the comments:
And the answer is, "No, not really". Some languages do have defined ways of using specific other language's calling conventions. For example, C++ allows you to to put
extern "C"
on declarations to tell the compiler that the declaration(s) in question use the C calling convention. Ada accomplishes the same thing withpragma Convention (X,...)
, where X is the convention name.C
,Fortran
, andCobol
are defined by the language, but anything else supported (eg: Windows'Stdcall
) is implementation defined.However, if you have a pair of languages whose compiler writers never thought of each other, then you have no choice but to tell both to use some third convention that they both know about (usually C's). For example, to get standard C++ and Ada to interoperate, you'd have the server code export its routines using the C convention, and tell the client code that the routines it is calling are using the C convention.
不同的语言肯定可以使用相同的库。例如,在旧的 Windows Visual Basic 上,动态加载 Windows API 函数是很常见的。
跨语言链接所需的只是就函数调用约定达成一致,并了解函数名称。前者需要通过查阅文档来完成;后者必须在创建对象或库的编译器中查找。例如,
gcc
将在不修改名称的情况下编译 C,因此您可以直接引用 C 源代码中的函数名称,而g++
将编译带有修改名称的 C++ 代码名称,并且您最好通过extern "C"
声明公开 C 函数。基本上,只要您的对象或库仅公开 C ABI,就应该广泛支持绑定到其他语言。例如,如果您想使用本机 C++ 库,那就要困难得多,因为在这种情况下,您的外语必须实现正确的 C++ ABI。这与从 Fortran 等程序中导出代码类似,但我相信可以只使用 C ABI。
Different languages can definitely use the same libraries. On the old Windows Visual Basic it was quite common to dynamically load Windows API functions, for instance.
All you need for inter-language linking is an agreement on the function's calling conventions, along with knowledge of the function names. The former has to be done by looking up the documentation; the latter has to be looked up in the compiler that created the objects or libraries. For example,
gcc
will compile C without mangling names, so you can refer directly to the function names as they are in your C source, whileg++
will compile C++ code with mangled names and you're best off exposing C functions viaextern "C"
declarations.Basically, as long as your objects or libraries expose only the C ABI, there should be widespread support for binding to other languages. It's a lot more difficult if you want to use a native C++ library, for instance, since in that case your foreign languages have to implement the correct C++ ABI. It's similar for exporting code from, say, Fortran, but I believe that one can be made to just uses the C ABI.
“标准”是在组合不同语言的程序时使用非损坏的名称。通过使用
extern "C"
声明 C++ 中的特定符号,可以关闭名称修改。 C 不会破坏名称。The "standard" is to use non-mangled names when combining programs from different languages. Name mangling can be turned off for specific symbols in C++ by declaring them with
extern "C"
. C does not mangle names.所有库可执行文件都包含某种类型的接口。如果不这样做,任何软件都无法与它们一起工作。内部方法更有可能被改变以提高效率。此外,许多语言允许您在编译器级别关闭“重整”。
链接,作为一个简单的解释(我可能会因此而被嘲笑?),就是打包到一个文件中。这些类保留与非链接库相同的接口,至少从外部编程的角度来看是这样。
All library executables contain some type of interface. If they did not, no software would be able to work with them. It is more likely internal methods get changed to be more efficient. In addition, many languages allow you to turn off "mangling" at the compiler level.
Linking, as a simple explanation (I will probably get dinked for this?), is packaging into a single file. The classes retain the same interface as non-linked libraries, at least from an external programming standpoint.