【问题标题】:Marshal c# struct to C struct is not working将 C# 结构编组到 C 结构不起作用
【发布时间】:2022-11-22 03:00:01
【问题描述】:

我想从 C# 调用以下 C 函数,但它不起作用:

/**
* \brief Register a tag callback functions.
* \param callback:  tag callback functions.
* \return None
*/
extern void nfcManager_registerTagCallback(nfcTagCallback_t *callback);

以下是所需参数的定义: (C代码)

/**
 * \brief NFC Tag callback function structure definition.
 */
typedef struct {
    /**
     * \brief NFC Tag callback function when tag is detected.
     * param pTagInfo       tag infomation
     */
    void (*onTagArrival) (nfc_tag_info_t *pTagInfo);

    /**
     * \brief NFC Tag callback function when tag is removed.
     */
    void (*onTagDeparture) (void);
}nfcTagCallback_t;

这是 nfc_tag_info_t 的定义: (C代码)

/**
 * \brief NFC tag information structure definition.
 */
typedef struct
{
    /**
     *  \brief indicates the technology of tag
     */
    unsigned int technology;
    /**
     *  \brief the handle of tag
     */
    unsigned int handle;
    /**
     *  \brief the uid of tag
     */
    char uid[32];
    /**
     *  \brief the uid length
     */
    unsigned int uid_length;
    /**
     *  \brief activated protocol
     */
    tNFC_PROTOCOL protocol;

}nfc_tag_info_t;

我尝试了以下内容: (C#代码)

    [DllImport("libnfc_nci_linux.so", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
    private static extern void nfcManager_registerTagCallback(IntPtr callback);


    [StructLayout(LayoutKind.Sequential)]
    public struct nfcTagCallback_t
    {
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public IntPtr onTagArrival;

        [MarshalAs(UnmanagedType.FunctionPtr)]
        public IntPtr onTagDeparture;
    }

    public static void onArrival(IntPtr intPtr)
    {
        Console.WriteLine("Arrival");
    }

    public static void onDeparture()
    {
        Console.WriteLine("Departure");
    }

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    public delegate void CallbackOnArrival(IntPtr intPtr);
    
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    public delegate void CallbackOnDeparture();

    [StructLayout(LayoutKind.Sequential)]
    private struct nfc_tag_info_t
    {
        /**
         *  \brief indicates the technology of tag
         */
        public uint technology;
        /**
         *  \brief the handle of tag
         */
        public uint handle;
        /**
         *  \brief the uid of tag
         */
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
        public char[] uid;
        /**
         *  \brief the uid length
         */
        public uint uid_length;
        /**
         *  \brief activated protocol
         */
        public byte protocol;

    }

我这样调用方法:

var nfcTagCallback = new nfcTagCallback_t();
nfcTagCallback.onTagDeparture = Marshal.GetFunctionPointerForDelegate(new CallbackOnDeparture(onDeparture));
nfcTagCallback.onTagArrival = Marshal.GetFunctionPointerForDelegate(new CallbackOnArrival(onArrival));

IntPtr testPointer = Marshal.AllocHGlobal(Marshal.SizeOf(nfcTagCallback));
Marshal.StructureToPtr(nfcTagCallback, testPointer, true);
nfcManager_registerTagCallback(testPointer); // <-- Exception (see below)

如果我运行此代码,则会抛出以下异常:

Unhandled exception. System.ArgumentException: Type 'PN7150_NFC.Program+nfcTagCallback_t' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.
   at System.Runtime.InteropServices.Marshal.SizeOfHelper(Type t, Boolean throwIfNotMarshalable)
   at System.Runtime.InteropServices.Marshal.SizeOf[T](T structure)
   at PN7150_NFC.Program.Main(String[] args) in /home/pi/Desktop/PN7150-NFC/PN7150-NFC/Program.cs:line 95

有人可以帮我吗?

【问题讨论】:

标签: c# c struct marshalling unmanaged


【解决方案1】:

您正在尝试将 IntPtr 编组为 FunctionPtr,即 should be used on delegates。您可以:

  1. onTagArrival定义为CallbackOnArrival,将onTagDeparture定义为CallbackOnDeparture
  2. 删除[MarshalAs(UnmanagedType.FunctionPtr)]

    最后,正如 @jdweng 在 cmets 中指出的那样,请注意调用约定。

【讨论】:

    猜你喜欢
    • 2010-12-17
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多