I have a piece of ObjC code from the great VFR PDF Viewer on GIT.
It is using CGPDFDictionaryGetString
to get a pointer to a string from a PDF annotation. 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.
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
Switching to branch 4.2 reveals that it seems to be there. 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.
[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;
}