0

http://www.parashift.com/c%2B%2B-faq/cpp-objs-passed-to-c.html

答案分为两部分。我猜第一部分是直到代码结束。

对于第一部分,我看到的是作者正在使用“C”链接指令(extern“C”)用于用 C 编写的函数或由 C 函数调用的 C++ 函数(见下文),所以链接会没问题.

extern void c_function(Fred*);  // c function 
extern Fred* cplusplus_callback_function(Fred*);  // c++ function

这是有道理的。

然后 Fred* 从 main() 一直传递到 c_function() [我猜这就是作者/常见问题解答关于将 C++ 对象传递给 C 函数的说法],然后到 cplusplus_callback_function() [对象从 C 传递回 C++ 域功能]。

所以第一个问题,我是否正确理解了上述内容?所以常见问题的答案只是“传递一个指针”对象?

第二个问题,作者在代码迷路后解释了什么。他突然谈到比较指针是否相等,基数和派生之间的指针转换等。他想说什么?那个指针在被传递给 c_function 之后就失去了它所有的魔力?如果它是指向派生类的基类指针,如果它传递给 C++ 函数而不是 C 函数,我们可以做更多的事情吗?

最后一个问题,我想我不知道 C++ 代码是否包含在 extern "C" 指令中,唯一改变的是链接,但没有别的?C++ 代码仍然是 C++,对吧?如果我用 C++ 编写所有代码,但故意将一些函数包装在 extern "C" 中,我会失去什么?

4

3 回答 3

1

所以常见问题的答案只是“传递一个指针”对象?

这还有一件事,那就是#ifndef __cplusplus,你需要

typedef struct Fred Fred;

即转发声明Fred为 a struct(注意 astruct和 aclass仅在默认访问权限上有所不同)。

他想说什么?那个指针在被传递给 c_function 之后就失去了它所有的魔力?

C++ 编译器理解继承并会在进行比较之前转换指针类型。相比之下,C 编译器没有继承的概念,实际上不允许将不同类型的指针指向单个对象,除非其中至少有一个void*char*unsigned char*。正如您在常见问题解答中看到的那样,void*在桥接 C 和 C++ 时,即使转换为也是微妙的。

简单的解决方案是只给程序的 C 端Base指针。即,如果可能的话,完全隐藏它的继承。

如果我用 C++ 编写所有代码,但故意将一些函数包装在 extern "C" 中,我会失去什么?

超载。您不能有两个具有相同名称的 C 链接函数,即

extern "C" {
    void foo(void);
    void foo(int);
}

不可能。

于 2012-07-29T13:18:09.480 回答
0

在 C++ 中,当您使用多重继承时,在将派生类的指针强制转换为其基类之一时,您可能会发生指针移位。

这是一个检查它的例子:

#include <stdio.h>

using namespace std;

class Base1
{
private:
   int data1;
};

class Base2
{
private:
   int data2;
};

class Derived : public Base1, public Base2 {};

int main()
{
   Derived *derived_pointer = new Derived();
   Base1 *base1_pointer = dynamic_cast< Base1* >( derived_pointer );
   Base2 *base2_pointer = dynamic_cast< Base2* >( derived_pointer );

   printf( "derived = %p\n", derived_pointer );
   printf( "base1 = %p\n", base1_pointer );
   printf( "base2 = %p\n", base2_pointer );

   printf( "dervied == base1_pointer = %d\n", derived_pointer == base1_pointer );
   printf( "derived == base2_pointer = %d\n", derived_pointer == base2_pointer );

   return 0;
}

我系统上的输出(用 g++ 4.6.3 编译)是:

derived = 0x9901008
base1 = 0x9901008
base2 = 0x990100c
dervied == base1_pointer = 1
derived == base2_pointer = 1

在这里我们看到,即使指向基类的指针不同,我们看到指针的比较表明它们是相等的,因为它们指向它们都是父类的类的对象)。AC 程序对继承类和基类一无所知,因此它只会比较内存中的地址。

于 2012-07-29T13:32:16.983 回答
0

对于问题的第一部分,c_function 接收 typedef struct Fred Fred 类型的指针;不是物体或结构。那么该对象如何在那里使用呢?这个 C 函数如何接收 Fred.a_ 的值?可以定义为在 c_function 中映射 a_ 吗?

参考: https ://isocpp.org/wiki/faq/mixing-c-and-cpp#cpp-objs-passed-to-c

于 2016-10-23T17:49:29.523 回答