如何从C调用C++函数
How do I call C++ functions from C?
我正在编写一个C程序(myapp),该程序需要使用特定的API;API是用C++编写的。我曾经使用过C和C++,但从来没有同时使用过这两种语言,我很困惑。
因此,API提供了以下目录,我将其放在名为include的文件夹中,与我的makefile处于同一级别:
libmyapi.a
api/api.h
我的主要源文件是src/myapp.c,其中包括使用#include "api/api.h"
的API。
我的make命令是(加上一些标志,我没有列出,因为我认为它们在这里不相关):
gcc -Linclude -lmyapi -Iinclude src/myapp.c -o lib/myapp.sp -lrt
我遇到的问题是api.h文件包含对名称空间等的引用
namespace MyAPI {
namespace API {
typedef SimpleProxyServer SimpleConnection;
}
}
显然C编译器不知道这意味着什么。
所以,我认为我需要使用C++编译器进行编译,但后来有人说我没有,我可以"包裹";";外部"C";,但我真的不明白。在网上阅读了之后,我不再继续了。
我需要用C++编译吗?
我需要";"包裹";代码,这意味着什么?我只是这样做吗:
#ifdef __cplusplus
extern "C" {
namespace MyAPI {
namespace API {
typedef SimpleProxyServer SimpleConnection;
}
}
}
#endif
还是我把线包起来
namespace MyAPI {
namespace API {
然后它们对应的}}?
头文件调用其他头文件,所以我可能需要在很多地方这样做。
到目前为止,我尝试过的所有变体都有错误和警告,但我不知道我是包装错误、设置g++编译器标志错误、使用错误的编译器,还是什么!如果我知道要使用的方法,我至少可以开始调试。
您可以编写一个小型C++程序,为API创建C绑定。
查看此API:
namespace MyAPI {
namespace API {
typedef SimpleProxyServer SimpleConnection;
}
}
您可以创建c_api.h
#ifdef __cplusplus
extern "C" {
#endif
struct api_handle_t;
typedef struct api_handle_t* api_handle;
api_handle myapi_api_create();
void myapi_api_some_function_using_api(api_handle h);
void myapi_api_destroy(api_handle h);
#ifdef __cplusplus
}
#endif
和c_api.cpp
#include "c_api.h"
#include <myapi/api/stuff.hpp>
struct api_handle_t
{
MyAPI::API::SimpleConnection c;
};
api_handle myapi_api_create()
{
return new api_handle_t;
}
void myapi_api_some_function_using_api(api_handle h)
{
//implement using h
}
void myapi_api_destroy(api_handle h)
{
delete h;
}
用C++编译器编译它,并在C项目中包含C_api.h文件,并链接到用C++编译器创建的库和原始库。
基本上,您的C++库需要导出纯C API。也就是说,它必须提供一个仅依赖于typedef
、struct
、enum
、预处理器指令/宏的接口(也许还有一些我忘了提的事情,但它必须都是有效的C代码)。如果没有这样的接口,就无法将C代码与C++库链接起来。
这个纯C API的头需要与C和C++编译器都可编译,但是,当你将其编译为C++时,你必须告诉C++编译器它是一个C接口。这就是为什么您需要将整个API封装在中
extern "C" {
//C API
}
当编译为C++时。但是,这根本不是C代码,因此必须向C编译器隐藏extern "C"
。这是通过添加预处理器指令来完成的
#ifdef __cplusplus1
extern "C" {
#endif
//C API
#ifdef __cplusplus1
}
#endif
如果无法更改库头,则需要创建一个包装器API,该包装器提供这种纯C API并调用相应的C++代码。
如何从C调用C++函数?
通过编写声明在C和C++的公共子集中有效的调用函数。并通过在C++中声明具有C语言链接的函数。
我遇到的问题是api.h文件包含对命名空间的引用
这样的头没有写在C和C++的公共子集中,因此它不能从C中使用。您需要写一个有效的C头才能在C中使用它。
我需要用C++编译吗(即使用g++)?
如果您有用C++编写的函数定义,那么您需要用C++编译器编译这些C++函数。如果您有C函数调用这些C++函数,那么您需要使用C编译器编译这些C函数。
一个最小的例子:
// C++
#include <iostream>
extern "C" void function_in_cpp() {
std::cout << "Greetings from C++n";
}
// C
void function_in_cpp(void);
void function_in_c(void) {
function_in_cpp();
}
您不能。您可以在C++程序中使用C函数。但是你不能使用C中的C++。当C++被发明时,它允许C函数的兼容性和重用,所以它被写为C的超集,允许C++调用所有C库函数。
但事实并非如此。当C被发明时,还没有定义C++语言。
调用C++函数的唯一方法是将整个项目转换为C++函数。。。您需要使用C++编译器(或者如果是纯C,则使用C编译器)编译C函数,但对于要调用C++函数的C函数,必须将其编译为C++。你应该用申报
extern "C" {
void my_glue_func(type1 param1, type2 param2, ...)
{
/* ... */
}
} /* extern "C" */
并将整个事情链接为C++程序(调用C++链接器)
这是因为C对函数重载、类初始化和实例构造函数调用等一无所知。因此,如果你甚至可以解开C++函数的名称,以便能够从C调用它们(你最好不要尝试这样做),它们可能会在未初始化的情况下运行,因此你的程序可能(最)会崩溃。
如果你的main()
函数恰好是一个C函数,那么没有问题。C++的设计考虑到了这一点,因此main()
被隐式地声明为extern "C"
。:)
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗