从delphi调用目标C代码块
我正在尝试在我的firemonkey应用程序中执行后台获取.
I'm trying to make background fetch work in my firemonkey application.
到目前为止,我的perfromFetchWithCompletionHandler被调用并下载新信息.
I've gotten so far that my perfromFetchWithCompletionHandler gets called and downloads new information.
问题是当我完成提取操作并需要调用completionHandler代码块时,应用程序挂起并且没有任何异常(至少可以读取)
The problem comes when I'm done with my fetch and need to call the completionHandler code block, the app hangs and I don't get any exception (that I can read at least)
设置:
TBackgroundFetchResultHandlerC = procedure ( AResult : NSUInteger ); cdecl;
..
..
procedure performFetchWithCompletionHandler(self : id; _cmd : SEL; application: PUIApplication; handler : TBackgroundFetchResultHandlerC );
..
..
objc_msgSend((UIApp as ILocalObject).GetObjectId,
sel_getUid('setMinimumBackgroundFetchInterval:'),
Interval);
class_addMethod( objc_getClass('DelphiAppDelegate') ,
sel_getUid('application:performFetchWithCompletionHandler:'),
@performFetchWithCompletionHandler,
'v@:@?'
);
..
..
procedure performFetchWithCompletionHandler(self : id; _cmd : SEL; application: PUIApplication; handler : TBackgroundFetchResultHandlerC );
var t : TThread;
begin
NSLog3('performFetchWithCompletionHandler:begin');
Handler(0); <<--Stops here
//Next line of code never gets called.
NSLog3(Format('performFetchWithCompletionHandler:done, done',[ FetchResult ]) );
end;
我尝试过使用函数指针类型的不同声明,但是由于它并不是函数指针,我想这就是它不起作用的原因.
I've tried with different declarations of the function pointer type, but as it isn't a function pointer exactly I guess that's why it won't work.
有什么想法吗?
谢谢 罗伯特
I've found a solution that works: imp_implementationWithBlock
procedure performFetchWithCompletionHandler(self : id; _cmd : SEL; application: PUIApplication; handler : id );
///将处理程序更改为键入id(指针)
//Changed the handler to type id (Pointer)
const
libobjc = '/usr/lib/libobjc.dylib';
{$IF NOT DECLARED(_PU)}
const
{$IFDEF UNDERSCOREIMPORTNAME}
_PU = '_';
{$ELSE}
_PU = '';
{$ENDIF}
{$EXTERNALSYM _PU}
{$ENDIF}
function imp_implementationWithBlock( block :id ) : IMP; cdecl; external libobjc name _PU + 'imp_implementationWithBlock';
function imp_removeBlock( anImp : IMP ) : integer; cdecl; external libobjc name _PU + 'imp_removeBlock';
///从libobjc添加了对imp_implementationWithBlock和imp_removeBlock的引用
//Added references to imp_implementationWithBlock and imp_removeBlock from libobjc
type IMP = function( self : id; cmd : SEL; Param1 : NSUInteger ) : id; cdecl;
///在这种情况下,使用一个NSUInteger参数将IMP声明为c函数,该函数对应于imp_implementationWithBlock返回的函数指针.
//Declared type IMP as a c function corresponding to the function pointer returned by imp_implementationWithBlock in this particular case with one NSUInteger parameter.
procedure performFetchWithCompletionHandler(self : id; _cmd : SEL; application: PUIApplication; handler : id );
var
ahandlerimp : IMP;
begin
.... //Code to perform fetch
ahandlerimp := imp_implementationWithBlock( handler ); //Create c function for block
ahandlerimp(self,_cmd,FetchResult ); //Call c function, _cmd is ignored
imp_removeBlock(ahandlerimp); //Remove the c function created two lines up
end;