我有一张来自GIT上伟大的VFR PDF Viewer的ObjC代码。
它使用CGPDFDictionaryGetString
从PDF注释中获取指向字符串的指针。然后它使用一些字节指针转换来获取最终的字符串。
在Monotouch中没有CGPDFDictionary.GetString()
但只有.GetName()
- 这是唯一返回字符串的方法,所以我认为必须是正确的方法,但它不起作用。
我可以很好地检索数组,字典,浮点数和整数 - 只有字符串似乎不起作用。
请参阅下面的小代码示例。
CGPDFStringRef uriString = NULL;
// This returns TRUE in the ObjC version and uriString is a valid pointer to a string.
if (CGPDFDictionaryGetString(actionDictionary, "URI", &uriString) == true)
{
// Do some pointer magic - how to do this in MT? Do I have to at all?
const char *uri = (const char *)CGPDFStringGetBytePtr(uriString);
// *uri now contains a URL, I can see it in the debugger.
}
我翻译得那样:
string sUri = null;
// This returns FALSE. Hence my sUri is NULL. Seems like GetName() is not the analogy to CGPDFDictionaryGetString.
if(oActionDic.GetName("URI", out sUri))
{
// I never get here.
}
修改 看一下Mono来源,我可以在Master分支中看到这个: // TODO:GetString - >返回CGPDFString
切换到分支4.2显示它似乎在那里。所以我从那里复制了代码但有两个问题:
[DllImport(Constants.CoreGraphicsLibrary)] public extern static IntPtr CGPDFStringGetLength(IntPtr pdfStr);
[DllImport (Constants.CoreGraphicsLibrary)]
public extern static IntPtr CGPDFStringGetBytePtr (IntPtr pdfStr);
public static string PdfStringToString (IntPtr pdfString)
{
if (pdfString == IntPtr.Zero)
return null;
int n = (int)CGPDFStringGetLength (pdfString);
unsafe
{
return new String ((char *)CGPDFStringGetBytePtr (pdfString), 0, n);
}
}
[DllImport (Constants.CoreGraphicsLibrary)]
extern static bool CGPDFDictionaryGetString (IntPtr handle, string key, out IntPtr result);
public static bool GetStringFromPdfDictionary (CGPDFDictionary oPdfDic, string key, out string result)
{
if (key == null)
throw new ArgumentNullException ("key");
IntPtr res;
if (CGPDFDictionaryGetString (oPdfDic.Handle, key, out res))
{
result = PdfStringToString (res);
return true;
}
result = null;
return false;
}
答案 0 :(得分:1)
如果您在源代码中使用不安全关键字,则需要在构建程序集时启用不安全。在MonoDevelop中,您可以通过以下方式执行此操作:
注意:如果没有此功能,您之前的版本就无法运行。
master 和 monotouch-4.2 之间的源代码在这种情况下应该是相同的。我会检查但是你可能正在查看GIT中的特定修订(在代码更新之前被推送)。我会检查以确定并编辑帖子。
更新:这是指向master的链接(即最新的可用代码),它显示:
public bool GetString (string key, out string result)
可用。但它确实依赖于不安全代码(在PdfStringToString中),如果不允许在复制/粘贴此代码的程序集中使用不安全的代码,则无法编译。
UPDATE2 :返回的值是UTF8编码的,因此从中创建的字符串需要正确解码(另一个System.String构造函数允许这样做)。以上指向master的链接应该已经指向固定版本。
答案 1 :(得分:0)
我不是使用不安全块的忠实粉丝,并设法实现此方法而不使用它。最初我尝试了不安全的样式,但是由于字符串存储在UTF8中,因此需要进行转换。
private bool PDFDictionaryGetString (IntPtr handle, string key, out string result)
{
IntPtr stringPtr;
result = null;
if (CGPDFDictionaryGetString(handle, "URI", out stringPtr)) {
if (stringPtr == IntPtr.Zero)
return false;
// Get length of PDF String
uint n = (uint) CGPDFStringGetLength (stringPtr);
// Get the pointer of the string
var ptr = CGPDFStringGetBytePtr (stringPtr);
// Get the bytes
var data = NSData.FromBytes(ptr, n);
// Convert to UTF8
var value = NSString.FromData(data, NSStringEncoding.UTF8);
result = value.ToString();
return true;
}
return false;
}