需要帮助将delphi记录转换为C#struct并将此结构传递给C dll:
type Transaction = record
pos_id: array[0..9] of char;
ev_type: array[0..4] of char;
amount: array[0..14] of char;
chip_reader_used: boolean;
internal_magstripereader_used: boolean;
track2data: array[0..99] of char;
card_usage_mode: array[0..4] of char;
receipt_directory: array[0..254] of char;
additional_info: array[0..999] of char;
event_number: array[0..9] of char;
original_filingcode: array[0..19] of char;
transaction_reasoncode: array[0..9] of char;
end;
Run Code Online (Sandbox Code Playgroud)
试过以下但没有工作:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public unsafe struct Transaction {
public fixed byte pos_id[10];
public fixed byte ev_type[5];
public fixed byte amount[15];
public bool chip_reader_used;
public bool internal_magstripereader_used;
public fixed byte track2data[100];
public fixed byte card_usage_mode[5];
public fixed byte receipt_directory[255];
public fixed byte additional_info[1000];
public fixed byte event_number[10];
public fixed byte original_filingcode[20];
public fixed byte transaction_reasoncode[10];
};
Run Code Online (Sandbox Code Playgroud)
和C函数是:
void Card_Event(struct)
Run Code Online (Sandbox Code Playgroud)
C#(由GetProcAddress加载)
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void Card_Event_Func(ref Transaction transaction);
IntPtr procAddr = GetProcAddress(_hDLL, "Card_Event");
if ( procAddr == IntPtr.Zero )
return false;
Card_Event_Func Card_Event = (Card_Event_Func)Marshal.GetDelegateForFunctionPointer(procAddr, typeof(Card_Event_Func));
Run Code Online (Sandbox Code Playgroud)
你应该UnmanagedType.ByValTStr用于字符串.这里不需要不安全的代码.你会发现下面的声明,使用字符串,比不安全的固定数组更容易使用.
请注意,您还需要为布尔值指定单字节编组.默认编组bool是BOOL与Win32 API函数兼容的4字节.
最后,我不确定你为什么选择打包记录.Delphi代码中没有任何迹象表明它已被打包.
所以,最终的翻译看起来像这样:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Transaction
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
public string pos_id;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public string ev_type;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
public string amount;
[MarshalAs(UnmanagedType.I1)]
public bool chip_reader_used;
[MarshalAs(UnmanagedType.I1)]
public bool internal_magstripereader_used;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string track2data;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public string card_usage_mode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
public string receipt_directory;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1000)]
public string additional_info;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
public string event_number;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string original_filingcode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
public string transaction_reasoncode;
};
Run Code Online (Sandbox Code Playgroud)
我不确定你是否正确转换了函数调用,因为你没有显示函数的函数本机代码声明.