我需要为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#中创建的代码之间存在更多不兼容性:
lppcc
,lppol
和lppop
是指针,因此应将它们创建为指针或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方法的定义也不正确,应该是(假设
CFSPI
是CFS_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/