gpt4 book ai didi

c++ - 在 isocpp.org 中是否有其他方法可以执行此示例?

转载 作者:太空宇宙 更新时间:2023-11-04 04:34:22 26 4
gpt4 key购买 nike

我试图在 this link in isocpp.org 的第二个常见问题解答中编译和链接第二个示例(见下文) .

Naturally, this works only for non-member functions. If you want to call member functions (incl. virtual functions) from C, you need to provide a simple wrapper. For example:

// C++ code:
class C {
// ...
virtual double f(int);
};
extern "C" double call_C_f(C* p, int i) // wrapper function
{
return p->f(i);
}

Now C::f() can be used like this:

/* C code: */
double call_C_f(struct C* p, int i);
void ccc(struct C* p, int i)
{
double d = call_C_f(p,i);
/* ... */
}

经过多次尝试,我在VS2015中成功执行了这个例子。但是我仍然不相信我必须在 other.cpp 中使用的声明 extern "C"struct C *p = &c; (我根本无法使代码适用于与此不同的任何东西)。请注意,C++ 编译器会针对所提及的声明发出以下警告:

warning C4099: 'C': type name first seen using 'class' now seen using 'struct'

main.c 是用 C 编译器编译的,other.cpp 是用 C++ 编译器编译的。

ma​​in.c

/* C code: */

#include <stdio.h>
extern struct C *p;
double call_C_f(struct C* p, int i);

void ccc(struct C* p, int i)
{
double d = call_C_f(p, i);
printf("%f", d);

}

int main()
{
ccc(p, 1);
}

其他.cpp

// C++ code:
class C {
public:
virtual double f(int i) { return i; };
} c;

extern "C" struct C *p = &c; // This is the declaration that I'm concerned about
// Is it correct?

extern "C" double call_C_f(C* p, int i) // wrapper function
{
return p->f(i);
}

最佳答案

extern "C"struct C *p = &c 行恕我直言,比实际有用更令人困惑。在同一个 C++ 编译单元中,您首先将 C 声明为一个类,然后是一个结构。正如在 that other question 中对 refs 的评论中所说的那样, 一次用 struct 声明一个类,一次用 class 声明一个类可能会导致 C++ 代码中的重整问题。

而且它是无用的,因为 C 不是 POD 结构(它包含方法,甚至是虚拟结构),它不能从 C 中用作结构,实际上你只能使用 C 代码中指向 C 的指针作为一个不透明的指针。

所以这一行应该写成:

extern "C" class C *p = &c;

向编译器声明您正在定义一个指向类 C 的指针,该指针具有名为 p 的外部链接,指向 c。从 C++ 的角度完美定义。

接下来从 C 的角度来看,你声明了外部指针 p,指向一个未定义的结构 C。C 将只允许你使用它几乎是一个空指针,这意味着你可以影响它并且将其传递给函数,但 p->xxx 会导致错误,因为 struct C 未在该编译单元中完全声明。

事实上下面的代码和你的完全一样,没有任何警告:

主.c

/* C code: */

#include <stdio.h>
extern struct D *p;
double call_C_f(struct D* p, int i);

void ccc(struct D* p, int i)
{
double d = call_C_f(p, i);
printf("%f", d);

}

int main()
{
ccc(p, 1);
return 0; /* never return random value to environment */
}

其他.cpp

// C++ code:
class C {
public:
virtual double f(int i) { return i; };
} c;

extern "C" C *p = &c;

extern "C" double call_C_f(C* p, int i) // wrapper function
{
return p->f(i);
}

struct D 的用法不是拼写错误。当然,我应该使用 struct C 来避免让读者感到困惑,但这对编译器来说不是问题,对链接器来说不是:main.c 中的 p 只是指向不透明的未完全声明的结构的指针。这就是为什么通常将不透明指针声明为 void * 的原因。

关于c++ - 在 isocpp.org 中是否有其他方法可以执行此示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32704184/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com