gpt4 book ai didi

objective-c - 在 Objective-C 完成 block 内运行 C 回调函数

转载 作者:行者123 更新时间:2023-11-30 16:30:32 24 4
gpt4 key购买 nike

我一直致力于使用 kivy/python 制作一个应用程序,我需要使用 obj-c 调用一些 ios 框架。所以我用 python->cython->c->obj-c->framework 制作了几层包装器。到目前为止,我已经完成了所有工作,直到回调函数一直返回到 python。现在回调在 cython->C->obj-c 层之间的某个地方失败(永远不会在 cython 中打印我的内容)。我觉得它是因为我试图将 user_func 作为 C 函数而不是 obj-c 函数来调用。我应该如何在 obj-c 中运行我的 C 回调函数?我在代码中添加了打印内容(无法单步执行我的设置),它打印生成的 token ,然后在 user_func 上崩溃。它也永远不会到达我的 cython 文件中的回调函数。因此,崩溃的根源介于两者之间。

- (void) retrieveTokenObjC:(char*)myKey andcardNumber:(char*)cardNumber andexpMonth:(int)expMonth andexpYear:(int)expYear andcvc:(char*)cvc anduser_func:(tokenfunc)user_func anduser_data:(void*)user_data {

NSString* NScardNumber = [NSString stringWithUTF8String:cardNumber];
NSString* NScvc = [NSString stringWithUTF8String:cvc];

STPCardParams *cardParams = [[STPCardParams alloc] init];
cardParams.number = NScardNumber;
cardParams.expMonth = expMonth;
cardParams.expYear = expYear;
cardParams.cvc = NScvc;

NSString *myPublishableKey = [NSString stringWithUTF8String:myKey];
STPAPIClient *apiClient = [[STPAPIClient alloc] initWithPublishableKey:myPublishableKey];

[apiClient createTokenWithCard:cardParams completion:^(STPToken *token,NSError *error) {

if (token == nil || error != nil) {
const char* errorChar = [error.localizedDescription UTF8String];
user_func(errorChar,user_data);
} else {
const char* tokenChar = [token.tokenId UTF8String];
user_func(tokenChar,user_data);
}
}];
}

之后是 obj-c header

#import <Foundation/Foundation.h>
typedef void (*tokenfunc) (const char *name, void *user_data);

@interface retToken : NSObject
- (void) retrieveTokenObjC:(char*)myKey andcardNumber:(char*)cardNumber andexpMonth:(int)expMonth andexpYear:(int)expYear andcvc:(char*)cvc anduser_func:(tokenfunc)user_func anduser_data:(void*)user_data;
@end

然后它进入 cython 的 c 包装器。

#include "stripe_ios_c.h"
#include "stripe_ios_imp.h"

void retrieveToken(char* myKey, char* cardNumber, int expMonth, int expYear, char* cvc,tokenfunc user_func, void *user_data){
retToken* retrieveToken = [[retToken alloc] init];
[retrieveToken retrieveTokenObjC:myKey andcardNumber:cardNumber andexpMonth:expMonth andexpYear:expYear andcvc:cvc anduser_func:user_func anduser_data:user_data];
}

然后是 c 包装器的头文件

typedef void (*tokenfunc)(const char *name, void *user_data);
void retrieveToken(char* myKey, char* cardNumber, int expMonth, int expYear, char* cvc,tokenfunc user_func, void *user_data);

最后是 cython 代码

__all__ = ['StripeWrapper']

cdef extern from "stripe_ios_c.h":
ctypedef void (*tokenfunc)(const char *name, void *user_data)
void retrieveToken(char* myKey, char* cardNumber, int expMonth, int expYear, char* cvc,tokenfunc user_func, void *user_data)

class StripeWrapper():

def __init__(self,**kwargs):
foo = 'bar'
pass

def getToken(self,tokenCallback,myKey,cardNumber,expMonth,expYear,cvc):

cdef bytes myKey_bytes = myKey.encode('utf-8')
cdef char* myKey_string = myKey_bytes
cdef bytes cardNumber_bytes = cardNumber.encode('utf-8')
cdef char* cardNumber_string = cardNumber_bytes
cdef bytes cvc_bytes = cvc.encode('utf-8')
cdef char* cvc_string = cvc_bytes

print myKey_bytes
print cardNumber_bytes
print cvc_bytes
print myKey_string
print cardNumber_string
print cvc_string

retrieveToken(myKey_bytes, cardNumber_bytes, expMonth, expYear, cvc_bytes, callback, <void*>tokenCallback)
print 'Debug 1'

cdef void callback(const char *name, void *tokenCallback):
print 'callback debug'
(<object>tokenCallback)(name.decode('utf-8'))

更新:我已经跟踪了这个问题,并且我的回调函数执行的问题是 python 回调在途中的某个地方被释放。

最佳答案

我解决了这个问题。这里的例子https://github.com/cython/cython/blob/master/Demos/callback/run_cheese.py如果您离开主/当前文件,则 cython 回调将不起作用。这是因为当您离开该文件时,内存就会被释放。推送 python 对象并使用后

cdef void callback(const char *name, void *tokenCallback):
(<object> tokenCallback).token = (name.decode('utf-8'))

我觉得 cython 的例子是一个坏例子,应该使用一个对象来发送回调,这样可以避免很多挫败感,但它终于起作用了!

关于objective-c - 在 Objective-C 完成 block 内运行 C 回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51097133/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com