Error calling a function from unmanaged dll

0

I have found documentation about PTOpenProvider, which I want to use from managed code (https://docs.microsoft.com/en-us/windows/desktop/api/prntvpt/nf-prntvpt-ptopenprovider).

I have declared PTOpenProvider as

/// <summary>
/// Opens an instance of a print ticket provider.
/// </summary>
/// <param name="pszPrinterName">A pointer to the full name of a print queue.</param>
/// <param name="dwVersion">The version of the Print Schema requested by the caller.</param>
/// <param name="phProvider">A pointer to a handle for the provider.</param>
/// <returns>If the operation succeeds, the return value is S_OK, otherwise the HRESULT contains an error code.</returns>
[DllImport("Prntvpt.dll")]
public static extern IntPtr PTOpenProvider(string pszPrinterName, uint dwVersion,IntPtr phProvider);

And call it as

var printerName = "Foxit Reader PDF Printer";           
IntPtr providerPointer = new IntPtr();
IntPtr result = MethodDeclarations.PTOpenProvider(printerName, 1,       providerPointer);

I receive result 0x80070057, which as I understand, indicates an error. The question is: how can i get human readable description of an error, and what should i generally in order to debug such code (calling unmanaged functions from managed code). Any links to helpful texts are welcome. Thank you!

c#
asked on Stack Overflow Jan 19, 2019 by metacube

2 Answers

2

COM specific error codes you can look up on Microsoft's dev website.

Your particular error 0x80070057 is the generic COM error E_INVALIDARG basically one or more arguments are invalid.

To answer your question, human readable descriptions are solely up to the discretion of the architect of said library to document or not. COM calls usually have decent documentation on where to go in the event of an error, but can be tricky to find.

When it comes to debugging the errors, that once again depends on the documentation provided with the library.

TL;DR

Check documentation, or google it. You're at the mercy of the library creator.

answered on Stack Overflow Jan 19, 2019 by Enfyve
0

The declaration of the imported function is not correct. There are two mistakes:

  1. You need to declare the third parameter as a ref parameter, because the function expects a pointer to the handle. (I use out in this case)
  2. You need to explicitly declare that the first parameter is a PWStr.

Tested code:

public enum HRESULT : uint
{
    S_FALSE = 0x0001,
    S_OK = 0x0000,
    E_INVALIDARG = 0x80070057,
    E_OUTOFMEMORY = 0x8007000E,
    E_INVALID_PRINTER_NAME = 0x80070709
}

[DllImport("Prntvpt.dll")]
public static extern HRESULT PTOpenProvider(
    [MarshalAs(UnmanagedType.LPWStr)]string pszPrinterName, 
    uint dwVersion, 
    [Out] out IntPtr phProvider);

[DllImport("Prntvpt.dll")]
public static extern HRESULT PTCloseProvider(
    IntPtr hProvider
);


private void button1_Click(object sender, EventArgs e)
{
    var printerName = @"Fax";
    IntPtr providerHandle;
    HRESULT result = PTOpenProvider(printerName, 1, out providerHandle);

    if(result == HRESULT.S_OK)
    {
        MessageBox.Show("OK. Handled obtained: " + providerHandle);

        PTCloseProvider(providerHandle);
    }
    else
    {
        MessageBox.Show("Error: " + result);
    }
}
answered on Stack Overflow Jan 30, 2019 by NineBerry

User contributions licensed under CC BY-SA 3.0