objective c - Error passing an UnsafeMutablePointer to a function -
i ios developer uses swift. using sdk in order communicate ip camera retrieve data it, , show user. ve project shipped sdk, written in obj c, , working without problems. problem not able pass parameter expected parameter type function. sdk old, integrated using static libraries , bridging header , able connect camera. think sdk written in c or c++, , having problems parameter conversion.
fos.h
typedef struct { int channel; long long time; unsigned int index; fosmediatype type; //is video or audio fosdecfmt fmt; //the format of video or audio. short iskey; short multiaudiopage; int frametag; union{ fosvideo_info video; //media type video. fosaudio_info audio; //media type audio. } media; unsigned long long pts; //pts. unsigned int len; //size of data. char data[0]; //just data. }attribute_packed fosdec_data; //save video or audio data,include video or audio information. .
objective c function, working
- (ibaction)login:(id)sender { //[self._imageview add] nsstring* str = [self._textfield text]; const char* url = [str utf8string]; char ip[128]; int port; char usr[64]; char pwd[64]; int count = sscanf(url, "%[^:]:%d/%[^:]:%s", ip, &port, usr, pwd); if (count != 4) { return; } mhandle = fossdk_create(ip, "", usr, pwd, port, port, fosipc_h264, foscntype_ip); //mhandle = fossdk_create(ip, "fasdfdsafdasfasd", usr, pwd, port, port, fosipc_h264, foscntype_p2p); if (mhandle == foshandle_invalid) { return; } [self._login setenabled:no]; [self._logout setenabled:yes]; [nsthread detachnewthreadselector:@selector(runinthread:) totarget:self withobject:^(void *param){ int usrprivilege = 0; foscmd_result ret = fossdk_login(mhandle, &usrprivilege, 500); if (foscmdret_ok != ret) { return; } ret = fossdk_openvideo(mhandle, fosstream_sub, 500); if (foscmdret_ok != ret) { return; } //char* framebuf = (char*)malloc(512*1024); fosdec_data* data = null; int outlen = 0; while (mhandle) { // fossdk_retainhandle(mhandle, &usrprivilege); if ( foscmdret_ok == fossdk_getvideodata(mhandle, (char**)&data, &outlen, fosdectype_rgb24) && outlen>0) { if (data->type == fosmediatype_video) { //int a=0; //a++; [self imagefromavpicture:data->data width:data->media.video.picwidth height:data->media.video.picheight]; } else{ } } usleep(20*1000); } }]; } .
the method signature in fos.h
fossdk foscmd_result fosapi fossdk_getvideodata(foshandle handle, char **data, int *outlen, fosdecfmt videofmt); .
when calling objective-c
fossdk_getvideodata(<#unsigned int handle#>, <#char **data#>, <#int *outlen#>, <#fosdecfmt videofmt#>) }]; .
when calling swift
fossdk_getvideodata(handle: uint32, data: unsafemutablepointer<unsafemutablepointer<int8>?>!, outlen: unsafemutablepointer<int32>!, videofmt: fosdecfmt) .
the error data parameter, exactly:
cannot convert value of type 'unsafemutablepointer<fosdec_data>' expected argument type 'unsafemutablepointer<int8>?' .
i ve tried changing declaration of data this, gives me error
let data = unsafemutablepointer<int8>(&fosdecdata) ambiguous use of 'init' .
this pointer stuff bit complicated able pair device camera, using methods used unsafemutablepointers too. however, cannot figure out how pass empy data object function.
the sdk outdated , bad documented, not help. anyway, need make working. hope help, coders! .
edit, ooper . here updated version in swift, produces unexpected error. result returned function 0, s correct. however, trying access original fosdeddata struct, have command failed due signal: segmentation fault: 11. how solve this? sorry long question, wanted accurate.
var mhandle : uint32 = fos_handle_init.rawvalue override func viewdidload() { super.viewdidload() //these functions camera pairing, , write result on mhandle, equal 0 , if functions work, otherwise 1 initializefos() startezlinkfos() sdkcreatefos() loginfos() openvideofos() var data: unsafemutablepointer<fosdec_data>? = nil var outlen : int32 = 0 while self.mhandle > 0 { let resultooper = withunsafemutablepointer(to: &data) { pointertofosdecdata in pointertofosdecdata.withmemoryrebound(to: unsafemutablepointer<int8>?.self, capacity: 1, { (pointertoint8pointer) in fossdk_getvideodata(self.mhandle, pointertoint8pointer, &outlen, fosdectype_rgb24) }) } if resultooper == foscmdret_ok && outlen > 0{ if let unwrdata = data { //if unwrdata.pointee.type == fosmediatype_video{ //produced output when try access pointee, fosdecdata struct need: //command failed due signal: segmentation fault: 11 //} } } usleep(20*1000) } }
first of all, using initializer of unsafemutablepointer in way may generate unexpected result , should never do:
let data = unsafemutablepointer<fosdec_data>(&fosdecdata) swift compiler may prepare temporary region inout parameter , pass address of region, released after call. unfortunately, code may work in cases, know codes work-in-some-cases can hard-to-fix bug.
second, in objective-c code, declare data fosdec_data* -- pointer fosdec_data -- , initializing null.
why trying initialize swift version of data &fosdecdata? there's no fosdecdata in objective-c code.
the equivalent swift code declaration of data should this:
var data: unsafemutablepointer<fosdec_data>? = nil you should declare data unsafemutablepointer<fosdec_data>? -- pointer fosdec_data -- , initialize nil.
in addition, needs var, fossdk_getvideodata rewrite valid pointer fosdec_data.
third, need pass unsafemutablepointer<unsafemutablepointer<int8>?>! second parameter of fossdk_getvideodata, &data generate pointer of type unsafemutablepointer<unsafemutablepointer<fosdec_data>?>.
to make sort of pointer type conversion, need use withmemoryrebound<t, result>(to:capacity:_:). , need call withunsafemutablepointer<t, result>(to:_:) pointer data.
let result = withunsafemutablepointer(to: &data) { pointertofosdecdataptr in //pointertofosdecdataptr: unsafemutablepointer<unsafemutablepointer<fosdec_data>?> pointertofosdecdataptr.withmemoryrebound(to: unsafemutablepointer<int8>?.self, capacity: 1) { pointertoint8ptr in //pointertoint8ptr: unsafemutablepointer<unsafemutablepointer<int8>?> //... } } so, swift code equivalent objective-c code this:
var data: unsafemutablepointer<fosdec_data>? = nil var outlen: int32 = 0 while mhandle != 0 { let result = withunsafemutablepointer(to: &data) { pointertofosdecdataptr in //pointertofosdecdataptr: unsafemutablepointer<unsafemutablepointer<fosdec_data>?> pointertofosdecdataptr.withmemoryrebound(to: unsafemutablepointer<int8>?.self, capacity: 1) { pointertoint8ptr in //pointertoint8ptr: unsafemutablepointer<unsafemutablepointer<int8>?> fossdk_getvideodata(mhandle, pointertoint8ptr, &outlen, fosdectype_rgb24) //implicit `return` works here , result passed `result`. } } if result == foscmdret_ok && outlen > 0 { if let data = data, data.pointee.type == fosmediatype_video { //... //self.imagefromavpicture... } else { } } usleep(20*1000) } edit
code updated reflect whole behavior of currently working objective-c code. (renamed mhandle mhandle in objective-c code.)
Comments
Post a Comment