【问题标题】:delphi record to C#delphi记录到C#
【发布时间】:2014-04-28 08:42:39
【问题描述】:

需要帮助将 delphi 记录转换为 C# 结构并将此结构传递给 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;

尝试以下但不工作:

[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 加载)

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

【问题讨论】:

  • “不工作”究竟是什么意思?
  • 表示dll调用正常通过但什么也不做。更正:c 调用采用指向结构的指针:Card_Event(struct*) Delphi 版本按预期工作。
  • 您是否考虑过对齐问题(打包记录、$Axxx 指令)? C# 结构具有 Pack=1 修饰符。在 Delphi 和 C# 中比较 sizeof(record)

标签: c# delphi pinvoke


【解决方案1】:

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

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

最后,我不确定你为什么选择打包唱片。 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;
};

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

【讨论】:

  • 非常感谢大卫!就是这样!现在可以正常工作了:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 2011-08-13
相关资源
最近更新 更多