简体   繁体   English

在OSX上的Delphi:如何将CFDictionaryRef转换为NSDictionary?

[英]Delphi on OSX: how to convert CFDictionaryRef to NSDictionary?

According to Apple documentation CFDictionaryRef and NSDictionary are Toll-Free Bridged Types . 根据Apple文档, CFDictionaryRefNSDictionaryToll-Free Bridged Types However, I get an AV in the following code, which MIGHT be because the bridge does not work with Delphi. 但是,我在下面的代码中得到了一个AV,这可能是因为该桥不适用于Delphi。

DADiskCopyDescription returns a CFDictionaryRef , which I wrap to a NSDictionary . DADiskCopyDescription返回CFDictionaryRef ,我将其包装为NSDictionary The pointer is not NIL, but when I access a function in the object, I get an AV: 指针不是NIL,但是当我访问对象中的函数时,会得到一个AV:

function osxGetRootVolumeUUID: string;
var lNSDictionary: NSDictionary;
    lDisk: DADiskRef;
    lCFUrl: CFURLRef;
    lSession: DASessionRef;
    lUUID: CFUUIDRef;
begin
  result := '';
  lSession := DASessionCreate(nil);
  lCFUrl := TNSURL.OCClass.fileURLWithPath(StrToNSStr('/'));
  lDisk := DADiskCreateFromVolumePath(nil,lSession,lCFUrl);
  lNSDictionary := TNSDictionary.Wrap(DADiskCopyDescription(lDisk));

  lUUID := lNSDictionary.objectForKey(kDADiskDescriptionVolumeUUIDKey); //<- AV here

  if lUUID<>nil then
    result := CFStringRefToStr( CFUUIDCreateString(nil, lUUID));
  lNSDictionary.release;
  CFRelease(lCFurl);
end;

I also tried to use CFBridgingRelease as suggested in this SO question but it gives error SIGABRT (6) : 我也尝试按照此SO问题的建议使用CFBridgingRelease ,但它给出了错误SIGABRT (6)

lNSDictionary := TNSDictionary.Wrap(CFBridgingRelease(DADiskCopyDescription(lDisk))); //gives error: SIGABRT (6)

How to make it work? 如何使其运作?

PS. PS。 Basically I just want to get the UUID of the root volume on OSX. 基本上,我只想获取OSX上根卷的UUID The function above is converted to Delphi from an Objective-C function we have used so far. 上面的函数已从到目前为止使用的Objective-C函数转换为Delphi。

Edit 编辑

Another thing I have tried is to avoid using NSDictionary , but this gives an error too, which could indicate that the problem is something else: 我尝试过的另一件事是避免使用NSDictionary ,但这也会产生错误,这可能表明问题是其他原因:

lCFDictionaryRef := DADiskCopyDescription(lDisk);
lUUID := CFDictionaryGetValue(lCFDictionaryRef, kDADiskDescriptionVolumeUUIDKey); //<- AV here

To convert a CFDictionaryRef to a TNSDictionary you must do it like this : 要将CFDictionaryRef转换为TNSDictionary,您必须这样做:

  var LNSDict: NSDictionary;
      LCFDict: CFDictionaryRef;

  LCFDict := DADiskCopyDescription(lDisk);
  try
    LNSDict:= TNSDictionary.Wrap(LCFDict );
  finally
    CFRelease(LCFDict);
  end;

so everything is good here, however i think maybe your av is in the way you access the object. 所以这里的一切都很好,但是我认为您的影音可能正在访问对象。 don't forget in IOS to always use getObjectID and not the pointer to the object 不要忘记在IOS中始终使用getObjectID而不是对象的指针

ex: pass to ios api (xxx as ILocalObject).GetObjectID and never pass to the IOS api directly xxx 例如:传递给ios api (xxx as ILocalObject).GetObjectID并且永远不要直接传递给IOS api xxx

so maybe it's must be (kDADiskDescriptionVolumeUUIDKey as ILocalObject).GetObjectID or something similar 所以也许一定是(kDADiskDescriptionVolumeUUIDKey as ILocalObject).GetObjectID或类似的东西

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM