delphi记录到C# [英] delphi record to C#

查看:169
本文介绍了delphi记录到C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

需要帮助将delphi记录转换为C#结构并将此结构传递给C dll:

need help converting delphi record to C# struct and passing this struct to 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;

尝试以下操作但不起作用:

tried following but not working:

[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];
};

和C函数是:

void Card_Event(struct)

C#(由GetProcAddress加载)

C# (loaded by 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));

推荐答案

您应该对字符串使用UnmanagedType.ByValTStr.这里不需要不安全的代码.您会发现下面的使用字符串的声明比不安全的固定数组更容易使用.

You should use UnmanagedType.ByValTStr for the strings. There is no need for unsafe code here. You'll find that declaration below, using strings, is much easier to use than unsafe fixed arrays.

请注意,您还需要为布尔值指定单字节编组. bool的默认编组格式是与Win32 API函数兼容的4字节BOOL.

Note that you also need to specify single byte marshalling for the booleans. The default marshalling for bool is a 4 byte BOOL compatible with Win32 API functions.

最后,我不确定您为什么选择打包记录.在Delphi代码中没有表明它已经打包.

Finally, I'm not sure why you chose to pack the record. There's no indication in the Delphi code that it is packed.

因此,最终的翻译如下:

So, the final translation looks like this:

[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;
};

我不确定您是否正确翻译了函数调用,因为您没有显示该函数的函数本机代码声明.

I'm not sure that you have translation the function call correctly because you've not shown a function native code declaration of the function.

这篇关于delphi记录到C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆