DLL等同于c#中的c++(关键字"IN")

本文关键字:quot IN 关键字 等同于 中的 c++ DLL | 更新日期: 2023-09-27 18:14:26

我的输入有一个问题

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

根据文档,错误0x30000001是"参数不正确",函数的原始定义是

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

输入是

[DllImport("mydll.dll")]
internal static extern IntPtr CreatePrintHandleSp(ref string lptPrinterName, ref PRINTINFO lpPrtInfo,ref string lptCnsiniPath);

我尝试用IN代替REF,但VS不接受它。我的结构没问题。它被GetDefaultPrintInfoSp正确使用。我尝试没有"ref",当我这样做,我有pinvokestack失衡

谢谢你的帮助

DLL等同于c#中的c++(关键字"IN")

没有c#的等号,因为IN不意味着任何东西,即使在c++中(它只是#define IN)。

LPTSTR表示指向TCHARS (T)的字符串(STR)的长指针(LP)。对于这种类型的参数,你应该简单地在c#中传递一个字符串,语言会为你处理它。

LPPRINTINFO意味着指向PRINTINFO的长指针(简单的指针),所以你应该把你的结构编组为非托管类型,并传递一个指针给它:

        int length = Marshal.SizeOf(typeof(PRINTINFO));
        IntPtr printInfoPtr = Marshal.AllocHGlobal(length);
        Marshal.StructureToPtr(DefaultPrintInfo, printInfoPtr, false);

,并更改函数原型:

[DllImport("mydll.dll")] internal static extern IntPtr CreatePrintHandleSp(string lptPrinterName, IntPtr lpPrtInfo, string lptCnsiniPath);

调用:CreatePrintHandleSp(nomImprimante, printInfoPtr, lienConfigImprimante)

完成后,应该释放非托管结构体:

Marshal.FreeHGlobal(printInfoPtr);

对于这部分代码中的异常要非常小心,因为如果你不调用Free,你将会在你的程序中导致内存泄漏。也许最好把free的调用放在finally块中。

我的导入类

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);
}
}
我的代码调用函数
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"

原函数格式为(C/c++)

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

看到错误了吗?谢谢你的帮助。