我需要为C dll导入一个函数GDPI,并且要在一个C#应用程序中使用。
我的问题是一个参数是一个CFSPI结构,在这个结构中我还有其他结构:
PII PPI LPPCC LPPOL LPPOP

我的问题是LPPOL的原始结构是C

typedef struct tagCFS_PRINT_OVLINFO {
DWORD dwOverlayType;
TCHAR szFormPath[MAX_PATH];
DWORD dwFormID;
BOOL bFormIdFixed;
} CFS_PRINT_OVLINFO, *LPCFS_PRINT_OVLINFO;


CFSPI结构为:

typedef struct tagCFS_PRINTINFO {
DWORD wCopies;
DWORD dwPrintInterval;
DWORD dwPrintSpeed;
DWORD dwPageID;
DWORD dwJobID;
CFS_PRINT_IMGINFO pii;
CFS_PRINT_PAPERINFO ppi;
LPCFS_PRINT_CCORRECTINFO lppcc;
LPCFS_PRINT_OVLINFO lppol;
LPCFS_PRINT_OPTION lppop;
LPVOID lpReserve1;
LPVOID lpReserve2;
DWORD dwReserve1;
DWORD dwReserve2;
} CFS_PRINTINFO, *LPCFS_PRINTINFO;


而函数定义是

int CFTGetDefaultPrintInfo(
IN LPTSTR lptPrinterName, // Printer name to obtain the print information
OUT CFSPI* lpPrtInfo // Default print information
);


我尝试通过在C#中定义

[DllImport("mydll.dll")]
internal static extern int CFTGetDefaultPrintInfo(string lptPrinterName, CFSPI lpPrtInfo);

internal struct CFS_PRINTINFO
{
    internal uint dwCopies;
    internal uint dwPrintInterval;
    internal uint dwPrintSpeed;
    internal uint dwPageID;
    internal uint dwJobID;
    internal CFS_PRINT_IMGINFO pii;
    internal CFS_PRINT_PAPERINFO ppi;
    internal CFS_PRINT_CCORRECTINFO lppcc;
    internal CFS_PRINT_OVLINFO lppol;
    internal CFS_PRINT_OPTION lppop;
    internal IntPtr lpReserve1;
    internal IntPtr lpReserve2;
    internal uint dwReserve1;
    internal uint dwReserve2;
}

internal struct CFS_PRINT_OVLINFO
{
    internal uint dwOverlayType; // Overlay, Print type
    internal StringBuilder szFormPath; // Form file path
    internal uint dwFormID; // Form file ID
    internal bool bFormIdFixed; // Wether to fix the form ID
}


当我调用函数时


  禁止在'app.CFS_PRINTINFO'类型的Marshaler le champ冠军中使用的块引用:在信息处理方面的定义,主要的/非常规的合并和无效的类型。


我尝试使用字符串,但未成功..

你有什么主意吗

谢谢

最佳答案

要创建固定缓冲区,请不要使用StringBuilder

internal unsafe struct CFS_PRINT_OVLINFO
{
    internal uint dwOverlayType; // Overlay, Print type
    internal fixed char szFormPath[MAX_PATH]; // Form file path
    internal uint dwFormID; // Form file ID
    internal bool bFormIdFixed; // Wether to fix the form ID
}


为了使此功能起作用,您必须启用不安全的代码。

但是C代码和您在C#中创建的代码之间存在更多不兼容性:
lppcclppollppop是指针,因此应将它们创建为指针或IntPtr

internal unsafe struct CFS_PRINTINFO
{
    internal uint dwCopies;
    internal uint dwPrintInterval;
    internal uint dwPrintSpeed;
    internal uint dwPageID;
    internal uint dwJobID;
    internal CFS_PRINT_IMGINFO pii;
    internal CFS_PRINT_PAPERINFO ppi;
    internal CFS_PRINT_CCORRECTINFO* lppcc;
    internal CFS_PRINT_OVLINFO* lppol;
    internal CFS_PRINT_OPTION* lppop;
    internal IntPtr lpReserve1;
    internal IntPtr lpReserve2;
    internal uint dwReserve1;
    internal uint dwReserve2;
}


甚至extern方法的定义也不正确,应该是(假设CFSPICFS_PRINTINFO):

[DllImport("mydll.dll")]
internal static extern int CFTGetDefaultPrintInfo(string lptPrinterName, out CFSPI lpPrtInfo);

关于c# - 在struct中的C#StringBuilder结构中导入C dll,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24780431/

10-17 02:37