简体   繁体   English

如何结合不同的编程语言

[英]How to combine different programming languages

I'm not asking about WHEN to link different programming langauges.不是在问何时链接不同的编程语言。

This is quite a general question but I'm personally working on Linux.这是一个相当普遍的问题,但我个人正在研究 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 .我想了解的是不同编程语言可以结合的过程,我找到了一篇关于结合C/C++/Fortran的好文章: http://www-h.eng.cam.ac.uk/help/tpl/语言/混合语言.html

From what I understand most compilers perform two stages:据我了解,大多数编译器执行两个阶段:

  1. Translating the language files into object files which contain machine code but still contain some symbols (possibly function names?)将语言文件翻译成 object 文件,其中包含机器代码但仍包含一些符号(可能是 function 名称?)

  2. Linking the object files together, only at this stage the Linker checks that the functions in the object files are callable.将 object 文件链接在一起,仅在此阶段 Linker 会检查 object 文件中的函数是否可调用。

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.我认为组合不同语言的问题是名称修改,这意味着当函数转换为 object 代码时,函数的名称会发生变化。

The questions are:问题是:

  1. 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?您不能以某种方式预先发现损坏的 function 名称,然后在编程语言中明确指定它们或者更好,难道没有软件已经这样做了吗?

  2. 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?我不完全了解动态库是如何链接的,但是不同的语言可以通过程序与动态库交互的相同方法进行交互吗?

ps The main intent is to call functions written in another language. ps 主要目的是调用用另一种语言编写的函数。

The issue with linking different object files together generally comes down to subroutine calling conventions.将不同的 object 文件链接在一起的问题通常归结为子程序调用约定。 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.基本上,当您调用位于另一个 object 文件中的例程时,您的编译器必须知道其他 object 文件将在内部命名其例程,如何传递其所有参数,以及什么(如果有)设置和清理代码例行程序将需要。 All this stuff is generally grouped together under the heading of calling convention s.所有这些东西通常都在调用约定的标题下组合在一起。

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. Linux 中的 C 调用约定不同于 ZAEA23489E8AA9B6406EB2A4 上的 C 调用约定

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. C 的约定是一种流行的约定,可用作“通用语言”,因为几乎每个平台都有 C 编译器。 However some platforms (eg: Windows) have multiple popular calling conventions.然而,一些平台(例如:Windows)有多种流行的调用约定。

So now we ask the question you asked in the comments:所以现在我们问你在评论中提出的问题:

Is there a common way to "tell the compiler to use the other language's calling convention"?有没有一种通用的方法来“告诉编译器使用其他语言的调用约定”?

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.例如, C++ 允许您将extern "C"放在声明上,以告诉编译器相关声明使用 C 调用约定。 Ada accomplishes the same thing with pragma Convention (X,...) , where X is the convention name. Ada 使用pragma Convention (X,...)完成了同样的事情,其中 X 是约定名称。 C , Fortran , and Cobol are defined by the language, but anything else supported (eg: Windows' Stdcall ) is implementation defined. CFortranCobol由语言定义,但其他支持的内容(例如:Windows 的Stdcall )是实现定义的。

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).但是,如果您有一对编译器编写者从未考虑过彼此的语言,那么您别无选择,只能告诉它们使用他们都知道的第三种约定(通常是 C)。 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.例如,要让标准C++ 和 Ada 互操作,您需要让服务器代码使用 C 约定导出其例程,并告诉客户端代码它正在调用的例程使用 Z0D61F834701D4122F8ZB 约定。

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.例如,在旧的 Windows Visual Basic 上,动态加载 Windows API 函数是很常见的。

All you need for inter-language linking is an agreement on the function's calling conventions, along with knowledge of the function names.语言间链接所需要的只是函数调用约定的协议,以及 function 名称的知识。 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, while g++ will compile C++ code with mangled names and you're best off exposing C functions via extern "C" declarations. 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, while g++ will compile C++ code with mangled names and you're best off exposing C functions via extern "C"声明。

Basically, as long as your objects or libraries expose only the C ABI, there should be widespread support for binding to other languages.基本上,只要您的对象或库仅公开 C ABI,就应该广泛支持绑定到其他语言。 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.例如,如果您想使用本机 C++ 库,则要困难得多,因为在这种情况下,您的外语必须实现正确的 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.从 Fortran 导出代码也是如此,但我相信可以只使用 C ABI。

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" .可以通过使用extern "C"声明 C++ 中的特定符号来关闭名称修改。 C does not mangle names. C 不会破坏名称。

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.至少从外部编程的角度来看,这些类保留了与非链接库相同的接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM