How can I call a method like StartXpsPrintJob , which optionally returns a pointer to a COM object, depending upon whether NULL is passed for the OUT parameter.
Example in C++ would be a call with printTicketStream
set NULL
:
IXpsPrintJob *job = NULL; IXpsPrintJobStream *jobStream = NULL; hr = StartXpsPrintJob( printerName, NULL, NULL, NULL, completionEvent, NULL, 0, &job, &jobStream, /* _Out_ IXpsPrintJobStream **printTicketStream */ NULL);
I know I could make the optional parameter IntPtr
rather than out IntPtr
and just pass IntPtr.Zero
, but that would require four P/Invoke signatures of this function to encompass all of the options, not to mention what the calling code would look like.
Since the parameter is really a pointer to a pointer which will hold the result, allocate a pointer and pass it as IntPtr
.
Example signature:
[DllImport("XpsPrint.dll", EntryPoint = "StartXpsPrintJob", PreserveSig = false)]
private static extern void StartXpsPrintJob(
// other parameters omitted for brevity
IntPtr printTicketStream);
Example use:
IXpsPrintJobStream ticketStream = null;
bool getTicketStream = false;
IntPtr ppTicketStream = IntPtr.Zero;
if (getTicketStream)
{
ppTicketStream = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)));
Marshal.StructureToPtr(IntPtr.Zero, ppTicketStream, false);
}
StartXpsPrintJob(ppTicketStream);
if (getTicketStream)
{
IntPtr pTicketStream = (IntPtr)Marshal.PtrToStructure(ppTicketStream, typeof(IntPtr));
ticketStream = (IXpsPrintJobStream)Marshal.GetTypedObjectForIUnknown(pTicketStream, typeof(IXpsPrintJobStream));
Marshal.FreeCoTaskMem(ppTicketStream);
}
//ticket stream now has the result from StartXpsPrintJob or null, if it was not requested
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.