我想从另一种语言调用C++构造函数,并且需要知道要给它提供什么参数。我认为应该是陈述的参数和"this“指针。但是,在Gnu G++中,"this“指针出现在第一位还是最后呢?除了"this“指针之外,还有其他的隐藏参数吗?
这个问题不涉及其他问题,例如名称损坏,因为我已经解决了这些问题。这个问题只是关于构造函数的参数。我使用的特定语言也不是问题,因为它是一种开发中的语言,这个问题适用于一般的非C++语言,而不仅仅是特定的语言。
编辑后添加:这是针对使用G++约定的英特尔处理器的。这应该回答了ABI涉及到什么的问题。
至于“外部C”,这不是C++代码。它调用C++代码,但是因为它本身不是C++代码,所以使用"extern C“是没有意义的。此外,它调用的C++代码必须按原样使用,不能添加诸如"extern C“之类的东西。
我正在寻找的并不是调用约定的精确正式定义。我只是想要一些线索来做实验。例如,C++编译器将"this“指针放在第一个参数以外的位置的情况有多常见?除了"this“指针之外,还有其他隐藏参数的情况有多常见。如果"this“指针不在第一位,它几乎总是在最后,还是有时在中间?等。
发布于 2018-11-07 03:36:05
this指针在参数列表中的位置由实现定义。如果您希望与另一种语言交互,请添加一个C包装器:
// Your class
struct MyClass {
MyClass(int, int);
void doSomething(char,int);
};
// C wrapper
void* construct_MyClass(int a, int b) {
return new MyClass(a, b);
}
void doSomething(void* thisPtr, char c, int a) {
static_cast<MyClass*>(thisPtr)->doSomething(c, a);
}这样,编译器将按照预期的顺序放置参数,让您的调用者代码与APIs交互。您需要在C函数的声明中插入use extern C,以保留C链接的名称。
发布于 2018-11-07 04:28:39
C++标准没有定义如何将this指针和任何参数传递给构造函数(或任何函数)。这是ABI (应用程序二进制接口)的工作,不同的编译器可以使用不同的ABI。ABI不是C++标准的一部分。
我假设你想要使用的两种语言都是使用编译器编译成机器码的,因为这会使讨论变得更容易。类似的原则适用于解释型语言和其他语言,但具体细节有所不同。
一般来说,为了正确地从另一种语言调用任何C++函数,这两种语言都必须由各自的语言编译器翻译成相同的ABI,或者必须有一种定义/记录的方法,以便两种不同的ABI进行互操作。换句话说,这两个编译器-以及它们生成的机器代码-都必须设计为可互操作。
实际上,C++标准规定了它如何在语言级别与C进行互操作。C不能使用所有的C++构造,但extern "C"函数是由C++编译器以允许从C调用它们的方式构建的。因此,兼容的C和C++编译器-或它们发出的代码-可以互操作,假设这两个编译器支持相同的ABI。例如,g++ (gnu的C++编译器前端)和gcc (gnu的C编译器前端)被设计为互操作,但它们(必然)不能与其他供应商的编译器互操作。从技术上讲,gnu C编译器输出的机器码可能会与其他供应商的C编译器输出的代码互操作,但要做到这一点,需要非常详细地了解两个编译器所支持的ABI是如何工作的(以及两个供应商有意提供的支持)。
对于要与C++互操作的其他语言,选项就不那么直接了。通常,它们的共同点是C -其他语言提供了与C进行互操作的工具,C++也是如此,因此一些C接口被用作两者之间的中介。例如,可以将在C++中实例化对象的代码放在extern "C"函数中。然后可以使用C++编译器编译该代码,生成的函数有一个允许从C代码调用它的接口。如果另一种语言(或编译器)支持与C语言互操作(即,为了调用C函数而符合正确接口的要求),则可以从其他语言调用该C函数。
发布于 2018-11-07 04:47:59
对于“
C”,这不是C++代码。
标记为extern "C"的C++代码是可以从C调用的C++代码,因此也可以从其他非C++代码调用。C语言是一种跨语言接口的通用语言。如果你会说C,你就可以和任何也会说C的人交谈,这几乎是编程语言世界中的每一个人。C ABI是相当简单和容易实现的。说得客气一点,C++ ABI并非如此(而且它们是C ABI的严格超集,所以无论如何您都必须实现它们)。
坚持使用与C兼容的接口。您不是世界上第一个需要从非C++代码创建C++对象的人。每个人都是通过extern "C"代码来实现的。
外部调用的C++代码必须按原样使用,不能添加诸如“
C”之类的东西。
您无需向现有代码添加任何内容即可与之交互。您编写新的C++代码,使其调用旧的C++代码,并将新代码标记为extern C。旧代码不会以任何方式被修改。
https://stackoverflow.com/questions/53178744
复制相似问题