简体   繁体   English

此CGPDFDictionaryGetString如何转换为Monotouch?

[英]How does this CGPDFDictionaryGetString translate into Monotouch?

I have a piece of ObjC code from the great VFR PDF Viewer on GIT. 我在GIT的VFR PDF Viewer中有一段ObjC代码。 It is using CGPDFDictionaryGetString to get a pointer to a string from a PDF annotation. 它使用CGPDFDictionaryGetString从PDF批注获取指向字符串的指针。 Then it uses some byte pointer conversion to get the final string. 然后,它使用一些字节指针转换来获取最终的字符串。 In Monotouch there is no CGPDFDictionary.GetString() but only a .GetName() - this is the only method that returns a string, so I assumed that must be the correct method but it does not work. 在Monotouch中,没有CGPDFDictionary.GetString() ,只有.GetName() -这是返回字符串的唯一方法,因此我假定该方法必须是正确的方法,但它不起作用。 I can retrieve arrays, dictionaries, floats and integers just fine - only the strings don't seem to work. 我可以很好地检索数组,字典,浮点数和整数-只有字符串似乎不起作用。

See the small code examples below. 请参见下面的小代码示例。

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.
}

I translated it like that: 我这样翻译:

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.
}

EDIT: Looking at the Mono sources I can see this in the Master branch: // TODO: GetString -> returns a CGPDFString 编辑:查看Mono源,我可以在Master分支中看到: // TODO:GetString->返回CGPDFString

Switching to branch 4.2 reveals that it seems to be there. 切换到分支4.2可以发现它似乎在那里。 So I copied the code from there but have two issues: 所以我从那里复制了代码,但是有两个问题:

  • I get an error about the "unsafe" keyword. 我收到有关“不安全”关键字的错误。 It tells me to add the "unsafe" command line option. 它告诉我添加“不安全”命令行选项。 What is that and is it a good idea to add it? 那是什么,添加它是个好主意吗? Where? 哪里?
  • It seems to run anyway but the app hangs when getting the CGPDFString. 它似乎仍然可以运行,但是在获取CGPDFString时应用程序挂起。

[DllImport (Constants.CoreGraphicsLibrary)] public extern static IntPtr CGPDFStringGetLength (IntPtr pdfStr); [DllImport(Constants.CoreGraphicsLibrary)]公共外部静态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;
    }

If you use the unsafe keyword in your source then you need to enable unsafe when building your assembly. 如果在源代码中使用unsafe关键字,则在构建程序集时需要启用unsafe In MonoDevelop you can do this by: 在MonoDevelop中,您可以通过以下方式做到这一点:

  • Right-click on the project; 右键单击该项目;
  • Select Options menu; 选择选项菜单;
  • Select General icon; 选择常规图标;
  • Click the Allow 'unsafe' code checkbox 点击允许“不安全”代码复选框
  • Click Ok button 单击确定按钮
  • Then rebuild. 然后重建。

Note: Your previous build should not have worked without this. 注意:没有此功能,您以前的版本应该无法工作。

Source code between master and monotouch-4.2 should be identical in this case. 在这种情况下, mastermonotouch-4.2之间的源代码应该相同。 I'll check but it's likely that you were looking at a specific revision in GIT (the was pushed before the code was updated). 我会检查,但是您可能正在查看GIT中的特定修订版(在更新代码之前已推送该修订版)。 I'll check to be sure and edit the post. 我将检查确定并编辑帖子。

UPDATE : This is the link to master (ie latest code available) and it shows: 更新 :这是母版的链接(即最新的可用代码),它显示:

public bool GetString (string key, out string result)

to be available. 可用。 However it does depend on unsafe code (inside PdfStringToString) which you should not have been able to compile without allowing unsafe code in the assembly where you copy/pasted this code. 但是,它确实取决于不安全的代码(在PdfStringToString内部),如果您在复制/粘贴此代码的程序集中没有不安全的代码,就不应该编译这些代码。

UPDATE2 : The value returned is UTF8 encoded so the string created from it needs to be decoded properly (another System.String constructor allows this). UPDATE2 :返回的值是UTF8编码的,因此需要正确解码由此创建的字符串(另一个System.String构造函数允许这样做)。 The above link to master should already point to the fixed version. 上面指向master的链接应该已经指向固定版本。

I'm not a big fan of using unsafe blocks, and worked out a way to implement this method without using one. 我不太喜欢使用不安全的块,因此想出了一种无需使用该块即可实现此方法的方法。 Initially I did try the unsafe style, however as the string is stored in UTF8 it needs to be converted. 最初,我确实尝试过不安全的样式,但是由于字符串存储在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;
} 

There's a full blog post here and working sample including complete source here featuring multipage swipe navigation and clickable links. 有一个完整的博客文章在这里 ,并包含完整的源工作样本这里设有多页刷卡导航和可点击的链接。

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

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