使用 EXC_BAD_ACCESS(..) 从 C++ 调用 Swift func
call swift func from c++ with EXC_BAD_ACCESS(...)
我正在研究 xcode8 swift 3.0 项目。它需要访问一个C++库,该库需要一个回调函数来异步地将数据发送回 swift 调用者。如果直接在 RegisterCallBack 函数中调用回调,则回调确实有效。但是,如果它在 RegisterCallBack 函数外部调用它,则崩溃。
在我的 swift 文件 ViewController 中.swift
override func viewDidLoad() {
super.viewDidLoad()
var closure: () -> Void = testfunc;
RegisterCallBack(closure)
run_swiftfunc()
}
func testfunc(){
print("test func in view contriller ");
}
....
在我的包装器.h文件中
...
void run_swiftfunc();
void RegisterCallBack(void (^closure)());
...
在我的包装器.cpp文件中
extern "C" {
typedef void (^callbackfunc)();
callbackfunc swiftFunc;
void RegisterCallBack(void (^closure)()){
swiftFunc = closure;
printf("function pointer 0x%x n", (void*) swiftFunc);
swiftFunc(); //works well
}
void run_swiftfunc(){
printf("function pointer 0x%x n", (void*) swiftFunc);
swiftFunc(); // fail, EXC_BAD_ACCESS
}
...
}
日志打印:注册回调函数指针0x1300cd30
run_swiftfunc
函数指针0x1300cd30
View Contriller 中的测试 FUNC
run_swiftfunc
函数指针0x1300cd30
(LLDB) ---->EXC_BAD_ACCESS(code =..
swiftfunc 地址相同,两者都0x1300cd30。如何保存 swiftfunc 块?
我发现该块只是堆栈,因此仅在函数范围内工作。我最终使用Block_copy来避免这个问题。现在我可以使用异步回调函数在 c++ 中调用 swift 函数
在我的包装器.cpp文件中
#include <Block.h>
extern "C" {
typedef void (^callbackfunc)();
callbackfunc swiftFunc;
void RegisterCallBack(void (^closure)()){
swiftFunc = Block_copy(closure);
printf("function pointer 0x%x n", (void*) swiftFunc);
swiftFunc(); //works well
}
void run_swiftfunc(){
printf("function pointer 0x%x n", (void*) swiftFunc);
swiftFunc();
}
...
}
在 cpp 文件中__strong
闭包。
//
// TestCallbacks.h
// XIO
//
// Created by Brandon T on 2016-07-06.
// Copyright © 2016 XIO. All rights reserved.
//
#ifndef TestCallbacks_h
#define TestCallbacks_h
#ifdef __cplusplus
extern "C" {
#endif
void run_swiftfunc();
void RegisterCallBack(void (^closure)());
#ifdef __cplusplus
}
#endif
#endif /* TestCallbacks_h */
//
// TestCallbacks.mm
// XIO
//
// Created by Brandon T on 2016-07-06.
// Copyright © 2016 XIO. All rights reserved.
//
#include "TestCallbacks.h"
#include <cstdio>
#ifdef __cplusplus
extern "C" {
#endif
typedef void (^callbackfunc)();
__strong callbackfunc swiftFunc;
void RegisterCallBack(void (^closure)()) {
swiftFunc = closure;
printf("function pointer %p n", (void*) swiftFunc);
swiftFunc();
}
void run_swiftfunc() {
printf("function pointer %p n", (void*) swiftFunc);
swiftFunc();
swiftFunc = nil;
}
#ifdef __cplusplus
}
#endif
然后我在桥接标头中包含TestCallbacks.h
。
然后我迅速地做到:
override func viewDidLoad() {
super.viewDidLoad()
let closure: @convention(block) () -> Void = self.testfunc
RegisterCallBack(closure)
run_swiftfunc()
}
func testfunc(){
print("test func in view contriller ");
}
我建议当你用完它时,你取消引用以防万一。
另一种选择是使用 Objective-C 运行时:
#include "TestCallbacks.h"
#include <cstdio>
#import <objc/runtime.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void(*callback)(id, SEL)
callback swiftCallback;
void RegisterCallBack(void (^closure)()) {
swiftCallback = (callback)imp_implementationWithBlock(closure);
printf("function pointer %p n", (void *) swiftCallback);
swiftCallback(nil, nil);
}
void run_swiftfunc() {
printf("function pointer %p n", (void *) swiftCallback);
swiftCallback(nil, nil);
imp_removeBlock((IMP)swiftCallback);
}
#ifdef __cplusplus
}
#endif
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++为什么尽管我调用了void函数,它却不起作用
- 构造函数正在调用一个使用当前类类型的函数
- 变量没有改变?通过向量的函数调用
- 没有为自己的结构调用列表推回方法
- 调用'begin(int [n])'没有匹配函数
- 什么时候调用析构函数
- 如何用参数值调用函数(仅在运行时已知)
- std::cout.imbue()多重调用
- 函数何时会在c++中包含stack_Unwind_Resume调用