我尝试在this link in isocpp.org的第二个常见问题解答中编译并链接第二个示例(见下文)。
当然,这仅适用于非成员函数。如果你想 从C调用成员函数(包括虚函数),您需要 提供一个简单的包装。例如:
// C++ code: class C { // ... virtual double f(int); }; extern "C" double call_C_f(C* p, int i) // wrapper function { return p->f(i); }
现在可以像这样使用C :: f():
/* 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中执行了这个例子。但是我仍然不相信我必须在extern "C" struct C *p = &c;
中使用的声明other.cpp
(我根本无法使代码与除此之外的任何东西一起工作)。请注意,C ++编译器会针对所提到的声明发出以下警告:
警告C4099:'C':使用现在看到的'class'首次看到的类型名称 '结构'
main.c
是使用C编译器编译的,other.cpp
是使用C ++编译器编译的。
的main.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);
}
other.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);
}
答案 0 :(得分:0)
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的角度来看,你声明了extern指针p
,指向一个未定义的struct C. C只允许你使用它几乎是一个void指针,这意味着你可以影响它并将它传递给函数,但p->xxx
会导致错误,因为struct C
未在该编译单元中完全声明。
事实上,以下代码与您的代码完全相同,没有任何警告:
的main.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 */
}
other.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 *
。