简体   繁体   English

C#中的DLL C ++等价性(关键字“ IN”)

[英]DLL C++ equilavence in C# (Keyword “IN”)

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 根据文档,错误0x30000001为“参数不正确”,函数的原始定义为

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. 我尝试用IN代替REF,但VS不接受。。我的结构还可以。 It is use correctly by GetDefaultPrintInfoSp. GetDefaultPrintInfoSp正确使用了它。 I try without "ref" when I do it I have PInvokeStackImBalance 我尝试不带“ ref”时遇到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 ). 没有C#等效项,因为IN即使在C ++中也没有任何意义(只是#define IN )。

LPTSTR means long pointer (LP) to a string (STR) of TCHARS (T). LPTSTR表示指向TCHARS(T)的字符串(STR)的长指针(LP)。 For this type of parameter, you should simply pass a string in C#, the language will take care of marshalling it for you. 对于这种类型的参数,您只需在C#中传递一个字符串,该语言将为您编组该字符串。

LPPRINTINFO means long pointer (simply pointer) to PRINTINFO, so you should marshall your structure as an unmanaged type and pass a pointer to it : LPPRINTINFO表示指向LPPRINTINFO长指针(简称指针),因此您应将结构编组为非托管类型,然后将指针传递给它:

        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) 调用方式: 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. 请特别注意这部分代码中的异常,因为如果不调用Free,将导致程序中的内存泄漏。 Perhaps it would be best to put the call to free in a finally block. 也许最好将通话免费放在finally块中。

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++) 原始函数格式为(在C / C ++中)

HANDLE CreatePrintHandleSp(
IN LPTSTR lptPrinterName,
IN LPPRINTINFO lpPrtInfo
);

Do you see some error? 看到错误了吗? Thanks you for help. 感谢您的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM