08-12-2015 01:19 PM - edited 08-12-2015 01:20 PM
I am using the WInspool.drv to determine printer status.
Using that DLL, I am trying to execute the GetPrinter function.
When I execute the function, it returns an error.
Can anyone advise me what I am doing wrong?
My seperate functions for getting default printer, opening and closing the printer works with success.
Solved! Go to Solution.
08-12-2015 01:40 PM
Sorry, still on LabVIEW 2012, can't open your VI.
What is the error? Do you get a dialog box reporting an error, or an error on the Error Out wire, or a return value indicating a Windows error?
08-12-2015 01:49 PM
I am sorry, allow me to clarify.
The error is not in the error cluster of the call library node.
What is occuring is the GetPrinter function is returning a value of 0, which is a function call failure.
I am positive the issue is my inputs into the function are incorrect. But I am not sure exactly what it is.
I am trying to pass the printer handle. I know this works since it works in my other functions.
I am also passing a Level of 2, a null value and size of 0 for the pointer, and pcbNeeded is a pointer return value.
I read online I should be able to pass a null by passing int32 value of 0. I think that is what I am doing.
I tested this function in C using the following example code sample, and I am trying to duplicate it in LabVIEW.
DWORD cByteNeeded;
GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded)
08-12-2015 01:51 PM
You have messed up the pPrinter input, it is a buffer of length cbBuf, not a single byte. I actually call this function twice, like many WinAPI functions it will tell you the buffer size you need (Always 144 on my 32-bit system). On the first call pPrinter is an empty U8 array and cbBuf is the length of this array (0). For the second call I use initialize Array to create an array of U8 with length given by pcbNeeded which is also wired to cbBuf and pcbNeeded for the second call.
You could probably just provide a safe, large value for the buffer, but I usually just use the two-step approach.
08-12-2015 01:56 PM
So are you saying I need to make the input pointer an array rather than a single variable?
Are there any examples?
Thank's for the advice. It's greatly appreciated.
08-12-2015 02:00 PM
What you call pPrinter needs to be an Array of type U8, choose 'Array Data Pointer'. You don't need the cluster, the only inputs you need to supply are the handle and the level.
08-12-2015 02:20 PM
I updated my VI, attached. The function now returns error 1097.
I would think you need more than just Level, pPrinter and the handle. If the API is a C function, shouldn't I have to pass all the inputs it requires?
Or does LabVIEW automatically ignore all of that?
MSDN resource for GetPrinter
https://msdn.microsoft.com/en-us/library/windows/desktop/dd144911(v=vs.85).aspx
BOOL GetPrinter(
_In_ HANDLE hPrinter,
_In_ DWORD Level,
_Out_ LPBYTE pPrinter,
_In_ DWORD cbBuf,
_Out_ LPDWORD pcbNeeded
);
08-12-2015 03:03 PM
You need to configure all the parameters in the Call Library Function Node. You do not need to actually wire values to all the parameters; LabVIEW will supply default values (for example, numeric values default to 0). When you are passing anything more than a scalar by pointer (a string or an array), you do need to pre-allocate in LabVIEW.
You should call GetPrinter twice. The first time, you only need to wire the hPrinter and Level. Take the pcbNeeded output from that call, and initialize an array of U8 to that size, then call GetPrinter a second time. For the second call, wire the initialized array to pPrinter, and the array size to cbBuf. You'll then need to convert the array output to the desired data, based on Level. The embedded strings in the output struct will be annoying because you'll need to copy the data from the pointer location into LabVIEW strings, and you don't know the length of those strings, but you could make it work.
08-12-2015 03:17 PM
If I do not wire cbBuf or pcbNeeded, I get a compile issue and the VI will not execute.
If I wire default values to these inputs, the function will return a 0, which is a failure.
My function prototype is:
int32_t GetPrinterA(int32_t handle, uint32_t level, uint8_t *pPrinter, uint32_t cbBuf , uint32_t *pcbNeeded);
I understand the function needs to be run twice. But should it not return a non-zero answer for the first run?
I am building the program up one step at a time.
08-12-2015 03:30 PM
If you save for previous, for LabVIEW 2012, I'll take a look. Please be more specific than "a compile issue." What's the exact text? Make sure you're using the correct calling convention. Nearly all Windows API functions use WINAPI.