Я получаю эту ошибку: -
Помощник по управляемой отладке 'PInvokeStackImbalance' Сообщение = Помощник по управляемой отладке 'PInvokeStackImbalance': 'Вызов функции PInvoke' CompuBytePos.net! Pos.net.ReceiptPrintClass :: OpenPrinter«разбалансировал стек. Это вероятно потому, что управляемая подпись PInvoke не совпадает с неуправляемой целевой подписью. Убедитесь, что соглашение о вызовах и параметры подписи PInvoke соответствуют целевой неуправляемой подписи. '
Это мой код: -
Imports System.IO
Imports System.Runtime.InteropServices
Public Class ReceiptPrintClass
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Structure DOCINFOW
<MarshalAs(UnmanagedType.LPWStr)> Public pDocName As String
<MarshalAs(UnmanagedType.LPWStr)> Public pOutputFile As String
<MarshalAs(UnmanagedType.LPWStr)> Public pDataType As String
End Structure
Structure PRINTER_DEFAULTS
Public pDatatype As IntPtr
Public pDevMode As IntPtr
Public DesiredAccess As Integer
End Structure
Public Structure AsciiControlChars
'Standard ASCII Control Characters
Public Shared Null As String = Chr(0) 'NUL
Public Shared StartOfHeader As String = Chr(1) 'SOH
Public Shared StartofText As String = Chr(2) 'SOT
Public Shared EndOfTransmission As String = Chr(4) 'EOT
Public Shared XON As String = Chr(17) 'XON
Public Shared Escape As String = Chr(27) 'ESC
Public Shared FileSperator As String = Chr(28) 'FS
Public Shared GroupSeperator As String = Chr(29) 'GS
Public Shared NewLine As String = Chr(13) & Chr(10) 'CR & LF
'ESCPOS Control Sequences
Public Shared ESCPOSlogo As String = AsciiControlChars.FileSperator & "p" & Chr(1) & AsciiControlChars.Null 'This will print logo 1, change Chr(1) to a different value (Chr(2) etc) to print different logos
Public Shared ESCPOSfontNormal As String = AsciiControlChars.Escape & "!" & AsciiControlChars.StartOfHeader
Public Shared ESCPOSFontDoubleHeight As String = AsciiControlChars.Escape & "!" & AsciiControlChars.XON
Public Shared ESCPOSFontDoubleWidth As String = AsciiControlChars.Escape & "!" & "!"
Public Shared ESCPOSFontDoubleHeightAndWidth As String = AsciiControlChars.Escape & "!" & "0"
Public Shared ESCPOSBarcodePrefix As String = AsciiControlChars.GroupSeperator & "h" & "(" & AsciiControlChars.GroupSeperator & "w" & AsciiControlChars.StartofText & AsciiControlChars.GroupSeperator & "k" & AsciiControlChars.EndOfTransmission
Public Shared ESCPOSBarcodeSuffix As String = AsciiControlChars.Null
Public Shared ESCPOSCut As String = AsciiControlChars.Escape & "m"
Public Shared ESCPOSKickDrawer As String = AsciiControlChars.Escape & "p" & Chr(0) & Chr(100) & Chr(250)
Public Shared ESCPOSBoldON As String = AsciiControlChars.Escape & "E" & AsciiControlChars.StartOfHeader
Public Shared ESCPOSBoldOFF As String = AsciiControlChars.Escape & "E" & AsciiControlChars.Null
Public Shared ESCPOSDoubleStrikeON As String = AsciiControlChars.Escape & "G" & AsciiControlChars.StartOfHeader
Public Shared ESCPOSDoubleStrikeOFF As String = AsciiControlChars.Escape & "G" & AsciiControlChars.Null
Public Shared ESCPOSUnderlineON As String = AsciiControlChars.Escape & "-" & AsciiControlChars.StartOfHeader
Public Shared ESCPOSUnderlineOFF As String = AsciiControlChars.Escape & "-" & AsciiControlChars.Null
End Structure
<DllImport("winspool.drv", EntryPoint:="OpenPrinterA", ExactSpelling:=True, SetLastError:=True, CallingConvention:=CallingConvention.Cdecl, CharSet:=CharSet.Ansi)>
Private Shared Function OpenPrinter(ByVal pPrinterName As String, ByRef hPrinter As IntPtr, ByRef pDefault As PRINTER_DEFAULTS) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="ClosePrinter", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartDocPrinterW", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal level As Int32, ByRef pDI As DOCINFOW) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="EndDocPrinter", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function EndDocPrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartPagePrinter", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function StartPagePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="EndPagePrinter", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function EndPagePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="WritePrinter", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function WritePrinter(ByVal hPrinter As IntPtr, ByVal pBytes As IntPtr, ByVal dwCount As Int32, ByRef dwWritten As Int32) As Long
End Function
<DllImport("kernel32.dll", EntryPoint:="GetLastError", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.Cdecl)>
Public Shared Function GetLastError() As Int32
End Function
' SendBytesToPrinter()
' When the function is given a printer name and an unmanaged array of
' bytes, the function sends those bytes to the print queue.
' Returns True on success or False on failure.
Public Shared Function SendBytesToPrinter(ByVal szPrinterName As String, ByVal pBytes As IntPtr, ByVal dwCount As Int32) As Boolean
Dim hPrinter As IntPtr ' The printer handle.
Dim dwError As Int32 ' Last error - in case there was trouble.
Dim di As New DOCINFOW ' Describes your document (name, port, data type).
Dim dwWritten As Int32 ' The number of bytes written by WritePrinter().
Dim bSuccess As Boolean ' Your success code.
Dim pd As PRINTER_DEFAULTS
Try
' Set up the DOCINFO structure.
With di
.pDocName = "RAW Document (Docket)"
.pDataType = "RAW"
End With
' Assume failure unless you specifically succeed.v ByVal src As String, ByRef hPrinter As Integer, ByVal pd As Integer
If OpenPrinter(szPrinterName, hPrinter, pd) Then
If StartDocPrinter(hPrinter, 1, di) Then
If StartPagePrinter(hPrinter) Then
' Write your printer-specific bytes to the printer.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, dwWritten)
EndPagePrinter(hPrinter)
End If
EndDocPrinter(hPrinter)
End If
ClosePrinter(hPrinter)
End If
' If you did not succeed, GetLastError may give more information
' about why not.
If bSuccess = False Then
dwError = GetLastError()
End If
Catch ex As Exception
msgbox(ex.message)
End Try
Return bSuccess
End Function
' When the function is given a string and a printer name,
' the function sends the string to the printer as raw bytes.
Public Shared Function SendStringToPrinter(ByVal szPrinterName As String, ByVal szString As String)
Dim pBytes As IntPtr
Dim dwCount As UInteger
' How many characters are in the string?
dwCount = szString.Length()
' Assume that the printer is expecting ANSI text, and then convert
' the string to ANSI text.
pBytes = Marshal.StringToCoTaskMemAnsi(szString)
' Send the converted ANSI string to the printer.
SendBytesToPrinter(szPrinterName, pBytes, dwCount)
Marshal.FreeCoTaskMem(pBytes)
Return 0
End Function
End Class
В этот момент возникает ошибка: -
If OpenPrinter(szPrinterName, hPrinter, pd) Then
If StartDocPrinter(hPrinter, 1, di) Then
If StartPagePrinter(hPrinter) Then
' Write your printer-specific bytes to the printer.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, dwWritten)
EndPagePrinter(hPrinter)
End If
EndDocPrinter(hPrinter)
End If
ClosePrinter(hPrinter)
End If
Этот класс принтера компилируется и отлично работает в framework 2.0, однако в 4.5 он встречает указанную ошибку.
Я искал на многих форумах, включенных stackoverflow, чтобы найти обходной путь для этой проблемы, помогаявыяснить, почему генерируется эта ошибка, будет очень ценно.