如何在Flutter中调用C++类的成员方法
问题根因
- C的名字修饰(Name Mangling)机制会对函数符号名做改造,和Flutter FFI依赖的C风格扁平符号规则不兼容,直接导出C成员函数会导致符号匹配失败
- 类的非静态成员函数依赖类实例才能调用,本身不能作为独立函数直接被FFI调用
解决方案
核心思路是新增一层C兼容的包裹层,所有暴露给FFI的函数都用extern "C"修饰,同时处理类实例的生命周期管理。
非静态类成员函数调用方案
这是适用范围最广的方案,步骤如下:
- 新增C兼容包裹代码,导出实例创建、销毁、成员函数调用三个接口:
#include "你的类头文件路径.h" // 创建类实例,返回指针供Dart侧持有 extern "C" __attribute__((visibility("default"))) __attribute__((used)) void* class_name_create() { return new(std::nothrow) ClassName(); } // 销毁类实例,避免内存泄漏 extern "C" __attribute__((visibility("default"))) __attribute__((used)) void class_name_destroy(void* instance) { delete static_cast<ClassName*>(instance); } // 包裹类成员函数调用 extern "C" __attribute__((visibility("default"))) __attribute__((used)) int class_name_add_native(void* instance, int n1, int n2) { auto* class_ptr = static_cast<ClassName*>(instance); // 可自行补充空指针等异常场景的处理逻辑 return class_ptr ? class_ptr->add_native(n1, n2) : 0; }
- Flutter侧调用流程:
- 先通过FFI查找上述三个导出函数
- 调用
class_name_create获取实例指针,Dart侧用Pointer<Void>类型存储 - 调用
class_name_add_native时传入实例指针+业务参数 - 实例使用完毕后调用
class_name_destroy释放内存
静态类成员函数调用方案
如果要调用的是类静态成员函数,不需要处理实例生命周期,直接包裹即可:
extern "C" __attribute__((visibility("default"))) __attribute__((used)) int class_name_add_native(int n1, int n2) { return ClassName::add_native(n1, n2); }
注意事项
所有暴露给Flutter FFI的函数必须加extern "C"修饰,强制编译器按照C语言规则生成符号名,避免名字修饰导致的符号找不到问题。
内容的提问来源于stack exchange,提问作者Jungwon
相关产品推荐
相关产品推荐

