I have one problem with my importation
DLL.GetDefaultPrintInfoSp(nomImprimante, lienConfigImprimante, out DefaultPrintInfo);
idPort = DLL.OpenPortSp(nomImprimante, nomPort, false, lienConfigImprimante);
Console.WriteLine(DLL.GetLastError().ToString("X"));//0
idPrinter = DLL.CreatePrintHandleSp( ref nomImprimante,ref DefaultPrintInfo,ref lienConfigImprimante);
Console.WriteLine(DLL.GetLastError().ToString("X"));//0x30000001
Console.WriteLine(idPort + " " + idPrinter); // XXXXXXX (one IntPtr) 0
According the documentation the error 0x30000001 is "Argument is incorrect" the original definition for function is
HANDLE CreatePrintHandleSp(
IN LPTSTR lptPrinterName,
IN LPPRINTINFO lpPrtInfo,
IN LPTSTR lptCnsiniPath
);
And my importation is
[DllImport("mydll.dll")]
internal static extern IntPtr CreatePrintHandleSp(ref string lptPrinterName, ref PRINTINFO lpPrtInfo,ref string lptCnsiniPath);
I try replace REF by IN but VS don't accept it.. My struct is ok. It is use correctly by GetDefaultPrintInfoSp. I try without "ref" when I do it I have PInvokeStackImBalance
Thank you for your help
There's no C# equivalent, since IN doesn't mean anything, even in C++ (it's just #define IN
).
LPTSTR
means long pointer (LP) to a string (STR) of TCHARS (T). For this type of parameter, you should simply pass a string in C#, the language will take care of marshalling it for you.
LPPRINTINFO
means long pointer (simply pointer) to PRINTINFO, so you should marshall your structure as an unmanaged type and pass a pointer to it :
int length = Marshal.SizeOf(typeof(PRINTINFO));
IntPtr printInfoPtr = Marshal.AllocHGlobal(length);
Marshal.StructureToPtr(DefaultPrintInfo, printInfoPtr, false);
, and change your function prototype:
[DllImport("mydll.dll")]
internal static extern IntPtr CreatePrintHandleSp(string lptPrinterName, IntPtr lpPrtInfo, string lptCnsiniPath);
Call as:
CreatePrintHandleSp(nomImprimante, printInfoPtr, lienConfigImprimante)
After you are done, you should free your unmanaged struct:
Marshal.FreeHGlobal(printInfoPtr);
Be very careful about exceptions in this part of code, since if you do not call Free you will cause memory leaks in your program. Perhaps it would be best to put the call to free in a finally block.
My importing Class
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace APP
{
[StructLayout(LayoutKind.Sequential)]
unsafe internal struct PRINTINFO
{
internal uint dwCopies;// According to the documentation from SDK in C++ variable type is DWORD
internal uint dwPrintInterval;//DWORD
internal uint dwPrintSpeed;//DWORD
internal uint dwPageID;//DWORD
internal uint dwJobID;//DWORD
internal PRINT_IMGINFO pii; // type PRINT_IMGINFO
internal PRINT_PAPERINFO ppi; // type PRINT_PAPERINFO
internal PRINT_CCORRECTINFO lppcc;// type LP_PRINT_CCORRECTINFO
internal PRINT_OVLINFO lppol; // type LP_PRINT_OVLINFO
internal PRINT_OPTION lppop; //LP_PRINT_OPTION
internal IntPtr lpReserve1; //LPVOID
internal IntPtr lpReserve2; //LPVOID
internal uint dwReserve1; //DWORD
internal uint dwReserve2; //DWORD
}
[StructLayout(LayoutKind.Sequential)]
internal struct PRINT_IMGINFO
{
internal uint dwSrcType; //DWORD
internal uint dwResolutionType;//DWORD
internal uint dwBandHeight; //DWORD
internal uint dwSrcWidthPixels; //DWORD
internal uint dwSrcHeightPixels; //DWORD
internal uint dwRotate; //DWORD
}
[StructLayout(LayoutKind.Sequential)]
internal struct PRINT_PAPERINFO
{
internal uint dwMediaType; //DWORD
internal uint dwUnit;//DWORD
internal uint dwPaperWidth;//DWORD
internal uint dwPaperHeight; //DWORD
internal uint dwTopMargin;//DWORD
internal uint dwBottomMargin; // DWORD
internal uint dwLeftMargin; // DWORD
internal uint dwRightMargin; // DWORD
internal uint dwGapMarkLength; //DWORD
internal uint dwLeftGap; // DWORD
internal uint dwRightGap; // DWORD
internal uint dwPaperID; // DWORD
internal uint dwEdgelessFlag; // DWORD
}
[StructLayout(LayoutKind.Sequential)]
unsafe internal struct PRINT_CCORRECTINFO
{
internal uint dwMatchingType; // DWORD
internal uint dwBrightness; // DWORD
internal uint dwMediaType; // DWORD
internal uint dwHalftone; // DWORD
internal uint dwColorExt; // DWORD
internal PRINT_CC_REG lppccreg; // LP_PRINT_CC_REG
internal PRINT_CC_CONDITION lppcccnd; // LP_PRINT_CC_CONDITION
}
[StructLayout(LayoutKind.Sequential)]
internal struct PRINT_CC_REG
{
internal UCMYK_VAL cmykPlainReg; // UCMYK_VA
internal UCMYK_VAL cmykPluralReg; // UCMYK_VA
}
[StructLayout(LayoutKind.Sequential)]
struct UCMYK_VAL
{
internal byte byK; // BYTE
internal byte byC; // BYTE
internal byte byM; // BYTE
internal byte byY; // BYTE
}
[StructLayout(LayoutKind.Sequential)]
internal struct PRINT_CC_CONDITION
{
internal uint dwSingleType; // DWORD
internal uint dwLevelCorrect; // DWORD
internal uint dwSharpness; // DWORD
internal int lBalanceCyan; // LONG
internal int lBalanceMagenta; // LONG
internal int lBalanceYellow; //LONG
internal int lBalanceBlack; // LONG
internal int lCCDensity; // LONG
internal int lContrast; // LONG
}
[StructLayout(LayoutKind.Sequential)]
unsafe internal struct PRINT_OVLINFO
{
internal uint dwOverlayType; // DWORD
internal fixed char szFormPath[256]; //TCHAR
internal uint dwFormID; // DWORD
internal bool bFormIdFixed; // BOOL
}
[StructLayout(LayoutKind.Sequential)]
unsafe internal struct PRINT_OPTION
{
internal PRINT_CUTINFO lppct; // LP_PRINT_CUTINFO
internal uint dwFormFeed; // DWORD
internal IntPtr lpvReserve1; // LPVOID
internal IntPtr lpvReserve2; // LPVOID
}
[StructLayout(LayoutKind.Sequential)]
internal struct PRINT_CUTINFO
{
internal uint dwCutType; // DWORD
internal uint dwCutByPageNum; // DWORD
internal uint dwCutInPageNum; // DWORD
internal uint dwCutConsNum; // DWORD
}
[StructLayout(LayoutKind.Sequential)]
internal struct PRINTCMD
{
internal byte[] lpbyCmdData; //OUT LPBYTE
internal uint dwDataSize; //OUT DWORD
}
[StructLayout(LayoutKind.Sequential)]
internal struct STATUS_INFO
{
internal uint dwSize; // DWORD
internal uint dwMainStatus; // DWORD
internal ushort wWarningStatus; // WORD
internal ushort wErrorStatus; // WORD
internal ushort wFatalStatus; // WORD
internal PAGEJOB_INFO cpi; // PAGEJOB_INFO
internal IntPtr lpcii; // LPVOID
}
[StructLayout(LayoutKind.Sequential)]
internal struct STATUS_INFO_2
{
internal uint dwSize; // DWORD
internal uint dwMainStatus; // DWORD
internal ushort wWarningStatus; // WORD
internal ushort wErrorStatus; // WORD
internal ushort wFatalStatus; // WORD
internal PAGEJOB_INFO cpi; // PAGEJOB_INFO
internal IntPtr lpcii; // LPVOID
internal uint dwSpeed; // DWORD
internal uint dwRemainNum; // DWORD
internal PRNPRG_INFO cppi; // PRNPRG_INFO
}
[StructLayout(LayoutKind.Sequential)]
internal struct STATUS_INFO_3
{
internal uint dwSize; // DWORD
internal uint dwMainStatus; // DWORD
internal ushort wWarningStatus; // WORD
internal ushort wErrorStatus; // WORD
internal ushort wFatalStatus; // WORD
internal PAGEJOB_INFO cpi; // PAGEJOB_INFO
internal IntPtr lpcii; // LPVOID
internal uint dwSpeed; // DWORD
internal uint dwRemainNum; // DWORD
internal PRNPRG_INFO cppi; // PRNPRG_INFO
internal uint dwMyHostID; // DWORD
internal JOBHIST cjh; // JOBHIST
}
[StructLayout(LayoutKind.Sequential)]
internal struct PAGEJOB_INFO
{
internal uint dwSerialCount; // DWORD
internal ushort wTotalPage; // WORD
internal ushort wMadeCount; // WORD
internal ushort wSetCount; // WORD
internal ushort wJobStatus; // WORD
}
[StructLayout(LayoutKind.Sequential)]
internal struct INK_INFO_CMYK
{
internal byte byBlackInk; // BYTE
internal byte byCyanInk; //BYTE
internal byte byMagentaInk; // BYTE
internal byte byYellowInk; // BYTE
internal byte byWasteInk; // BYTE
internal byte byReserved; // BYTE
}
[StructLayout(LayoutKind.Sequential)]
internal struct PRNPRG_INFO
{
internal ushort wTotalStep; //WORD
internal ushort wCurrentStep; // WORD
}
[StructLayout(LayoutKind.Sequential)]
internal struct JOBHIST
{
internal uint dwJhHostID; // DWORD
internal uint dwJobID; // DWORD
internal ushort wPrntCount; // WORD
internal ushort wReserve;//WORD
}
[StructLayout(LayoutKind.Sequential)]
unsafe internal struct SETTING_INFO
{
internal SLPTM_INFO lpcslp; // LP_SLPTM_INFO
internal HEADADJ_INFO_1 lpchai; // LPVOID
internal uint[] lpdwDevInfo; // LPDWORD
internal IntPtr lpclpi; // LPVOID
}
[StructLayout(LayoutKind.Sequential)]
internal struct SLPTM_INFO
{
internal uint dwSleepTime; // DWORD
internal uint dwDeepTime; // DWORD
}
[StructLayout(LayoutKind.Sequential)]
internal struct HEADADJ_INFO_1
{
internal CMYK_VAL cmykV; // CMYK_VAL
internal CMYK_VAL cmykH; // CMYK_VAL
internal uint dwHeadAdjType; // DWORD
}
[StructLayout(LayoutKind.Sequential)]
internal struct CMYK_VAL
{
internal byte cK; //char
internal byte cC; //char
internal byte cM; //char
internal byte cY; //char
}
[StructLayout(LayoutKind.Sequential)]
internal struct DEVICE_INFO
{
internal ushort wParticulSet; //WORD
internal byte byOptionSet; //BYTE
internal byte byDevAbility;//BYTE
}
[StructLayout(LayoutKind.Sequential)]
internal struct LATPOS_INFO
{
int iCutPos; // int
int iStopPos; // int
}
[StructLayout(LayoutKind.Sequential)]
internal struct END_INFO
{
internal uint dwCmdType; // DWORD
internal uint dwEndStatus; // DWORD
}
[StructLayout(LayoutKind.Sequential)]
internal struct RF_INFO
{
internal int iSetRFIDNum; //int
internal RFID_SET crs; // RFID_SET
}
[StructLayout(LayoutKind.Sequential)]
internal struct RFID_SET
{
internal byte byPageId; // BYTE
internal byte byUniqueId; // BYTE
}
[StructLayout(LayoutKind.Sequential)]
internal struct DATA_INFO
{
internal uint dwMainteId; // DWORD
internal int iGetDataSize; // int
}
[StructLayout(LayoutKind.Sequential)]
unsafe internal struct ORGPOS_INFO
{
internal TK_INFO lpTKGap1; //LPTK_INFO
internal TK_INFO lpTKGap2; //LPTK_INFO
}
[StructLayout(LayoutKind.Sequential)]
internal struct TK_INFO
{
internal int iTPass_TKNum; // int
internal int iReflec_TKNum; // int
}
[StructLayout(LayoutKind.Sequential)]
internal struct SLANTADJ_INFO_2
{
internal CMYK_VAL cmykSln1; // CMYK_VAL
internal CMYK_VAL cmykSln2; // CMYK_VAL
internal uint dwReserved; // DWORD
}
[SuppressUnmanagedCodeSecurityAttribute]
internal class NativeMethods
{
[DllImport("mydll.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "GetDefaultPrintInfo")]
internal static extern int GetDefaultPrintInfo(string lptPrinterName, out PRINTINFO lpPrtInfo);
[DllImport("mydll.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CreatePrintHandle")]
internal static extern IntPtr CreatePrintHandle(string lptPrinterName, IntPtr lpPrtInfo);
[DllImport("mydll.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CreatePrintHandle")]
internal static extern IntPtr CreatePrintHandle(string lptPrinterName, out PRINTINFO lpPrtInfo);
[DllImport("mydll.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "StartJobCmd")]
internal static extern int StartJobCmd(IntPtr hPrinter, PRINTCMD printcmd);
[DllImport("mydll.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "CreateJobHandle")]
internal static extern IntPtr CreateJobHandle(string lptPrinterName, IntPtr lpPrtInfo);
[DllImport("mydll.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "OpenPort")]
internal static extern IntPtr OpenPort(string lptPrinterName, string lptPortName, bool bAttribute);
}
}
And my code for call the function
NativeMethods.GetDefaultPrintInfo(nomImprimante, out DefaultPrintInfo);
idPort = NativeMethods.OpenPort(nomImprimante, nomPort, false);
Console.WriteLine("ID Port: " + idPort + " " + Marshal.GetLastWin32Error().ToString("X"));// Result is "ID Port: 892100681 0"
int length = Marshal.SizeOf(typeof(PRINTINFO));
IntPtr printInfoPtr = Marshal.AllocHGlobal(length);
Marshal.StructureToPtr(DefaultPrintInfo, printInfoPtr,true);
idPrinter = NativeMethods.CreatePrintHandle(nomImprimante, printInfoPtr);
Console.WriteLine("ID Printer: " + idPrinter + " " + Marshal.GetLastWin32Error().ToString("X"));// Result is "ID Port: 0 30000001"
idPrinter = NativeMethods.CreatePrintHandle(nomImprimante, out DefaultPrintInfo);
Console.WriteLine("ID Printer: " + idPrinter + " " + Marshal.GetLastWin32Error().ToString("X"));// Result is "ID Port: 0 30000001"
Original function format is(in C/C++)
HANDLE CreatePrintHandleSp(
IN LPTSTR lptPrinterName,
IN LPPRINTINFO lpPrtInfo
);
Do you see some error? Thanks you for help.
User contributions licensed under CC BY-SA 3.0