- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我是一名使用 swift 的 ios 开发者。我正在使用 sdk 与 ip 摄像头通信,从中检索数据,并将其显示给用户。我有一个 sdk 附带的项目,它是用 obj c 编写的,并且运行没有问题。问题是我无法将参数从函数传递到预期的参数类型。SDK 很旧,我使用静态库和桥接头将其集成,并且能够成功连接到相机。我认为sdk是用c或c++写的,我基本上是参数转换有问题。
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 is video.
FOSAUDIO_INFO audio; //Media type is audio.
} media;
unsigned long long pts; //Pts.
unsigned int len; //Size of data.
char data[0]; //Just data.
}ATTRIBUTE_PACKED FOSDEC_DATA; //Save the video or audio data,include video or audio information.
.
Objective C 函数,当前有效
- (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);
}
}];
}
.
fos.h中的方法签名
FOSSDK FOSCMD_RESULT FOSAPI FosSdk_GetVideoData(FOSHANDLE handle, char **data, int *outLen, FOSDECFMT videoFmt);
.
从 objective-c 调用时
FosSdk_GetVideoData(<#unsigned int handle#>, <#char **data#>, <#int *outLen#>, <#FOSDECFMT videoFmt#>)
}];
.
从swift调用时
FosSdk_GetVideoData(handle: UInt32,
data: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>!,
outLen: UnsafeMutablePointer<Int32>!,
videoFmt: FOSDECFMT)
.
错误是数据参数,正是:
Cannot convert value of type 'UnsafeMutablePointer<FOSDEC_DATA>' to expected argument type 'UnsafeMutablePointer<Int8>?'
.
我试过将数据声明更改为此,但它给了我这个错误
let data = UnsafeMutablePointer<Int8>(&fosdecData)
Ambiguous use of 'init'
.
这个指针有点复杂,但我能够使用同样使用 unsafeMutablePointers 的方法将我的设备与相机配对。但是,我不知道如何将这个空数据对象传递给函数。
SDK 已过时且文档错误,这无济于事。无论如何,我需要让它工作。希望能得到一些帮助,谢谢各位码农!.
编辑,感谢 OOPer.这是 swift 中的更新版本,它实际上会产生意外错误。从函数返回的结果现在是 0,所以它是正确的。但是,在尝试访问原始 FosdedData 结构时,我有一个 Command failed due to signal: Segmentation fault: 11。我怎么能解决这个问题?抱歉问题很长,我想准确一点。
var mhandle : UInt32 = FOS_HANDLE_INIT.rawValue
override func viewDidLoad() {
super.viewDidLoad()
//These functions basically do camera pairing, and write result on mhandle, which is equal to 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 i try access pointee, which is actually the fosdecData struct i need:
//Command failed due to signal: Segmentation fault: 11
//}
}
}
usleep(20*1000)
}
}
最佳答案
首先,使用UnsafeMutablePointer
的初始化器以这种方式可能会产生意想不到的结果,你永远不应该这样做:
let data = UnsafeMutablePointer<FOSDEC_DATA>(&fosdecData)
Swift 编译器可能会为 inout 参数准备一个临时区域,并传递该区域的地址,该地址在调用后立即释放。不幸的是,此代码在某些情况下可能有效,但您知道在某些情况下有效的代码可能是一个难以修复的错误。
其次,在您的 Objective-C 代码中,您声明 data
作为FOSDEC_DATA*
-- 指向 FOSDEC_DATA
的指针-- 并将其初始化为 NULL
.
为什么要尝试初始化 data
的 Swift 版本?与 &fosdecData
?没有 fosdecData
在您的 Objective-C 代码中。
声明 data
的等效 Swift 代码应该是这样的:
var data: UnsafeMutablePointer<FOSDEC_DATA>? = nil
您应该声明data
作为UnsafeMutablePointer<FOSDEC_DATA>?
-- 指向 FOSDEC_DATA
的指针-- 并将其初始化为 nil
.
另外还需要是var
, 你的 FosSdk_GetVideoData
会将其重写为指向 FOSDEC_DATA
的有效指针.
第三,需要通过UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>!
到 FosSdk_GetVideoData
的第二个参数,但是&data
会生成一个 UnsafeMutablePointer<UnsafeMutablePointer<FOSDEC_DATA>?>
类型的指针.
要进行这种指针类型转换,需要使用withMemoryRebound<T, Result>(to:capacity:_:)
.你需要调用withUnsafeMutablePointer<T, Result>(to:_:)
获取指向 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>?>
//...
}
}
因此,您的 Swift 代码相当于您的 Objective-C 代码将是这样的:
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 and the result is passed to `result`.
}
}
if result == FOSCMDRET_OK && outlen > 0 {
if let data = data, data.pointee.type == FOSMEDIATYPE_VIDEO {
//...
//self.imageFromAVPicture...
} else {
}
}
usleep(20*1000)
}
编辑
代码更新以反射(reflect)当前工作 Objective-C 代码的整体行为。 (在 Objective-C 代码中将 mhandle
重命名为 mHandle
。)
关于objective-c - 将 UnsafeMutablePointer 传递给函数时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45324330/
我正在使用 Swift 的 C API,对于我需要调用的方法之一,我需要给出一个 UnsafeMutablePointer>> 更多信息: 快速界面: public func presage_pred
函数: public func OSAtomicCompareAndSwapPtr(_ __oldValue: UnsafeMutableRawPointer!, _ __newValue: Unsa
我正在尝试使用 NSView 的 getRectsBeingDrawn,但我不太确定如何转换它需要的变量。 它的定义是: func getRectsBeingDrawn(rects: UnsafeMu
更新到 Swift 3 后,我的代码出现了一些问题。我在转换之前有这段代码: extension NSData { func castToCPointer() -> T { let mem
我真的被一个愚蠢但看似简单的问题弄疯了......我必须将 Data 转换为 AVAudioPCMBuffer。 寻找this question这似乎很容易,但随着 Swift 3 的出现,一切都发生
我需要使用一个使用 UnsafeMutablePointer?>! 的函数作为参数。它是用 Objective-C++ 框架编写的,我通过桥接 header 访问它: - (void) applyFi
我的 Swift 项目中有这个 EZAudio 方法,用于从麦克风捕获音频: func microphone(microphone: EZMicrophone!, hasAudioReceived b
我刚开始弄乱图像处理,我遇到了几个非常奇怪的问题,或者至少我认为是这样。我假设我犯了一些非常愚蠢的错误。 我本来打算就此发布另一个问题,但是使用下面的代码有时我也会得到随机噪声,而不是用户抽取数字的像
在main.swift文件,我们调用了我们的收据检查系统(由 Receigen 生成)。在 Swift 2 中,main.swift阅读: startup(Process.argc, UnsafeMu
我在 Swift 中创建了一个名为 RGB 的结构,非常简单: struct PixelRGB { var r: CUnsignedChar = 0 var g: CUnsignedC
我正在使用 SceneKit 的 SCNParticleSystem 构建一个测试应用程序。它有一个回调,可让您修改每个帧上的粒子属性。这个回调的签名是 typealias SCNParticleMo
Accelerate 框架的 Swift 签名 vDSP_biquadm()函数包括 UnsafeMutablePointer> 的参数类型和 UnsafeMutablePointer> . 如何在
请帮助语法: __weak typeof (self) weakSelf = self; [self.audioFile getWaveformDataWithCompletionBlock:^(fl
这段代码在 Swift2.3 中运行良好,现在我将其转换为 Swift3。所以我收到这个错误。有人知道如何解决这个问题吗? var cmdLnConf: OpaquePointer? filepriv
我构建了一个小结构,其中包含伪 C 字符串 UnsafeMutablePointer。现在我想添加一种方法来获取字符串的长度,但有些行为非常奇怪: struct Char { let valu
1. let context = CGContext(...) 2. context.draw(...) 3. let buffer = UnsafeMutablePointer(context.da
在 C 中,我有以下代码来分配一个具有适当大小的 AudioBufferList,然后用相关数据填充它。 AudioObjectPropertyScope scope = mIsInput ? kAu
我正在尝试将我的 Swift 2 代码转换为最新的语法 (Swift 3)。我收到以下错误: Cannot invoke initializer for type 'UnsafeMutablePoin
var a = [1,2,3] let ptr1 = UnsafeMutablePointer(&a[0]) //works fine let index = 0 let ptr2 = UnsafeM
在我创建的结构中(在Xcode 10.1,Swift 4.2上)观察到的属性上使用UnsafeMutablePointer时,出现了一些意外的行为。请参阅以下游乐场代码: struct NormalT
我是一名优秀的程序员,十分优秀!