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

Popular posts from this blog

python - Selenium remoteWebDriver (& SauceLabs) Firefox moseMoveTo action exception -

html - How to custom Bootstrap grid height? -

transpose - Maple isnt executing function but prints function term -