- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我试图在 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++ 编译器编译的。
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);
}
其他.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/
我在编程时发现了很多有趣的事情,其中之一是: enum class Foo { FOO_THING, FOO_TOO }; int main() { Foo foo {'d'};
我试图在 this link in isocpp.org 的第二个常见问题解答中编译和链接第二个示例(见下文) . Naturally, this works only for non-member
我要关注CppCoreGuidelines尽可能接近,但我在配置 clang-format 时遇到了一些问题。 如何配置 clang-format 以符合 isocpp 核心指南? 例如,以下准则给我
我从 isocpp.org 'Get started' 设置了一个最小的 MinGW (nuwen)这是为 windows 编译的 gcc 版本 6.1.0 这是我的代码 #include #inc
我是一名优秀的程序员,十分优秀!