C++ 如何调用c++;类及其方法,从c文件
我试图访问C++类,并从<代码> .c/c>文件中调用它的方法。< /p> 我用谷歌搜索这个主题,找到了这个 它说:C++ 如何调用c++;类及其方法,从c文件,c++,c,C++,C,我试图访问C++类,并从 .c/c>文件中调用它的方法。< /p> 我用谷歌搜索这个主题,找到了这个 它说: C++中可以写“代码>外部”C“函数”,访问类 M< /Cord>对象,并从C代码调用它们。 这里是一个C++函数,用来调用成员函数 Foo:< /强> extern "C" int call_M_foo(M* m, int i) { return m->foo(i); } struct M; // you can supply
C++中可以写“代码>外部”C“<代码>函数”,访问类<代码> M< /Cord>对象,并从C代码调用它们。
<强>这里是一个C++函数,用来调用成员函数<代码> Foo:< /强>
extern "C" int call_M_foo(M* m, int i) { return m->foo(i); }
struct M; // you can supply only an incomplete declaration
int call_M_foo(struct M*, int); // declare the wrapper function
int f(struct M* p, int j) // now you can call M::foo
{
return call_M_foo(p, j);
}
我的问题是,我应该把绕线放在哪里?在我的C++ <代码> .h >代码>文件中?还是C.h
文件
它接着说:
下面是一个使用类M
的C代码示例:
extern "C" int call_M_foo(M* m, int i) { return m->foo(i); }
struct M; // you can supply only an incomplete declaration
int call_M_foo(struct M*, int); // declare the wrapper function
int f(struct M* p, int j) // now you can call M::foo
{
return call_M_foo(p, j);
}
但是如何/在哪里在我的C文件中创建类M
?
我应该把上面的代码放在哪里?C.h
文件?C++ <代码> .h /代码>文件?还是C.C
文件
多谢各位
感谢GMan的详细回答。
我确实听从了你的建议。但是我的.c
文件中出现编译错误
main.c:33:./some_class.h:24:错误:应为“=”,“,”,“;”,”“”标记之前的asm'或'属性 /some_class.h:25:error:expected')在“”标记之前
./some_class.h:26:error:expected')在“*”标记之前 这是我的
一些课程.h
行24-26
:
#ifdef __cplusplus
class M {
public:
M();
virtual ~M();
void method1(char* name, char* msg);
};
extern "C" {
#else
struct M;
#endif
/* access functions line 24-26 are here*/
M* M_new(void);
void M_delete(M*);
void M_method1(M*, char*, char*);
#ifdef __cplusplus
}
#endif
出于某种原因,我的C编译器不喜欢GMan
中的外部“C”
的原始测试.h
。所以我必须修改到上面。C编译器似乎不喜欢/不理解结构M代码>行
任何想法都将被赏识。
你需要在C++头文件和实现文件中分割它。 foo.h:extern "C" int call_M_foo(M* m, int i);
struct M;
extern "C" M* create_M();
foo.cc:
extern "C" int call_M_foo(M* m, int i) {
return m->foo(i);
}
extern "C" M* create_M() {
return new M;
}
要创建M类型的对象,您需要一个类似的函数:
foo.h:
extern "C" int call_M_foo(M* m, int i);
struct M;
extern "C" M* create_M();
foo.cc:
extern "C" int call_M_foo(M* m, int i) {
return m->foo(i);
}
extern "C" M* create_M() {
return new M;
}
您链接到的站点已经有了答案: 您可以在 由C和C共享的头文件 C++代码: 您最多可以声明一个函数 重载集的外部“C” 下面是 包装函数:
基本上,可以在两个共享的头上声明函数原型,如果C.是C++,则在函数中可以添加外部“C”修饰符,以确保函数可以从一个对象中访问,然后在C++代码中像往常一样在函数中定义函数的主体,如在类中需要的话,在C中使用函数,像正常值一样。
您的头文件,它在C和C++代码之间共享:#ifdef __cplusplus // only actually define the class if this is C++
class some_class
{
public:
int some_method(float);
};
#else
// C doesn't know about classes, just say it's a struct
typedef struct some_class some_class;
#endif
// access functions
#ifdef __cplusplus
#define EXPORT_C extern "C"
#else
#define EXPORT_C
#endif
EXPORT_C some_class* some_class_new(void);
EXPORT_C void some_class_delete(some_class*);
EXPORT_C int some_class_some_method(some_class*, float);
然后您的源文件:
#include "some_foo.h"
int some_class::some_method(float f)
{
return static_cast<int>(f);
}
// access functions
EXPORT_C some_class* some_class_new(void)
{
return new some_class();
}
EXPORT_C void some_class_delete(some_class* this)
{
delete this;
}
EXPORT_C int some_class_some_method(some_class* this, float f)
{
return this->some_method(f);
}
<>如果你认真地想混合C和C++,你会想要宏的< /P>
以下是一些示例宏,它们可以使这一过程变得更简单:
// in something like c_export.h
// extern "C" macro
#ifdef __cplusplus
#define EXPORT_C extern "C"
#else
#define EXPORT_C
#endif
// new
#define EXPORT_C_CLASS_NEW(classname) EXPORT_C \
classname * classname##_new(void)
#define EXPORT_C_CLASS_NEW_DEFINE(classname) \
EXPORT_C_CLASS_NEW(classname) \
{ return new classname (); }
// repeat as much as you want. allows passing parameters to the constructor
#define EXPORT_C_CLASS_NEW_1(classname, param1) EXPORT_C \
classname * classname##_new( param1 p1)
#define EXPORT_C_CLASS_NEW_1_DEFINE(classname, param1) \
EXPORT_C_CLASS_NEW_1(classname, param1) \
{ return new classname (p1); }
// delete
#define EXPORT_C_CLASS_DELETE(classname) EXPORT_C \
void classname##_delete( classname * this)
#define EXPORT_C_CLASS_DELETE_DEFINE(classname) \
EXPORT_C_CLASS_DELETE(classname) \
{ delete this; }
// functions
#define EXPORT_C_CLASS_METHOD(classname, methodname, ret) EXPORT_C \
ret classname##_##methodname##( classname * this)
#define EXPORT_C_CLASS_METHOD_DEFINE(classname, methodname, ret) \
EXPORT_C_CLASS_METHOD(classname, methodname, ret) \
{ return this->##methodname##(); }
// and repeat as necessary.
#define EXPORT_C_CLASS_METHOD_1(classname, methodname, ret, param1) EXPORT_C \
ret classname##_##methodname( classname * this, param1 p1)
#define EXPORT_C_CLASS_METHOD_1_DEFINE(classname, methodname, ret, param1) \
EXPORT_C_CLASS_METHOD_1(classname, methodname, ret, param1) \
{ return this->##methodname##(p1); }
等等。我们的标题/来源变成:
// header
#include "c_export.h" // utility macros
#ifdef __cplusplus // only actually define the class if this is C++
class some_class
{
public:
int some_method(float);
};
#else
// C doesn't know about classes, just say it's a struct
typedef struct some_class some_class;
#endif
// access functions
EXPORT_C_CLASS_NEW(some_class);
EXPORT_C_CLASS_DELETE(some_class);
EXPORT_C_CLASS_METHOD_1(some_class, some_method, int, float);
// source
#include "some_foo.h"
int some_class::some_method(float f)
{
return static_cast<int>(f);
}
// access functions
EXPORT_C_CLASS_NEW_DEFINE(some_class);
EXPORT_C_CLASS_DELETE_DEFINE(some_class);
EXPORT_C_CLASS_METHOD_1_DEFINE(some_class, some_method, int, float);
我们走了。C将使用指针与引用接口:
// c source, if some_method took a reference:
float f = 10.0f;
int i = some_class_some_method(myInstance, &f);
我们通过“参考”传递
f
。您这里有几个问题,所以我将分别回答
我的问题是,我应该把绕线放在哪里?在我的C++ .h文件中?还是c.h文件
<> >代码>外部“C”<代码>行进入C++文件。它本质上告诉编译器
限制所有的代码,将代码“>外部”C”/代码>块到C++的C子集,并
相应地导出在此区域中声明的函数
但是如何/在哪里在我的c文件中创建类M
你不能。C没有类的概念,也绝对没有
直接实例化类的方法。你必须导出一个C函数
在C++文件中创建类并将其作为指针返回。那你呢
可以在C应用程序周围传递该指针。实际上,您不能修改
直接在C应用程序中初始化,因为C不支持类,并且
您的C++编译器可以插入“隐藏”变量来进行内部簿记。
类的实际声明
我应该把上面的代码放在哪里
使用struct
ure指针的代码段位于C文件中。你是
被迫使用struct
ure指针,因为C根本不支持类。
您可以在C实现中的任何位置使用该函数进行函数调用
文件,就像普通的C函数调用一样。您需要的所有信息都在您提供的链接中。您只需要理解C和C++代码之间需要严格的分离。
void f(int)代码>可能会被C编译器损坏: > F f>代码>,但是C++编译器可能会选择一个非常不同的名称,例如“代码> fytnt/CODE >,因此链接器不知道它们应该是相同的。”
然而:
extern“C”void f(int)代码>
将被C++编译器修改为Fi,但C编译器会在 Extn“C”< /C>中窒息。为了避免这种情况,您应该使用以下方法:
#ifdef __cplusplus
extern "C" {
#endif
void f(int);
#ifdef __cplusplus
} /* closing brace for extern "C" */
#endif
现在,上面的整个部分都可以保存在一个.h文件中,正如sun.com
文章所述,它是一个混合语言标题
这意味着.c或.cpp文件可以#包含此头文件,并且代码可以调用f()代码>
和a.c或.cpp文件都可以#包括
此头并实现它:
void f()
{
}
现在的好一点是.cpp文件可以实现它调用任何它喜欢的C++代码。
现在回答您的具体问题:
第一个代码示例只能放在.cpp文件中
第二个代码示例只能放在.c文件中
额外的