首页 > 解决方案 > 如何从 C# P/Invoke 中的 void 指针指针获取结果

问题描述

我正在尝试围绕 Windows 烛光库编写 C# 包装器,但我被困在这个函数上:

typedef void* candle_list_handle;

DLL bool __stdcall candle_list_scan(candle_list_handle *list);

这是我尝试过的:

        [DllImport("candle_api.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool candle_list_scan(ref IntPtr listPtr);

        public candle_list_t? Scan()
        {
            IntPtr ptr = new IntPtr();
            var res = candle_list_scan(ref ptr);

            var list = Marshal.PtrToStructure<candle_list_t>(ptr);


            if (res)
            {
                return list;
            }
            else
                return null;
        }

我也试过:

        [DllImport("candle_api.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern bool candle_list_scan(ref IntPtr listPtr);

        public candle_list_t? Scan()
        {
            IntPtr ptr = new IntPtr();
            var res = candle_list_scan(ref ptr);

            var list = Marshal.PtrToStructure<candle_list_t>(ptr);

            if (res)
            {
                return list;
            }
            else
                return null;
        }

但两者都没有正常工作。这是设置列表的 C 代码:


bool __stdcall candle_list_scan(candle_list_handle *list)
{
    if (list==NULL) {
        return false;
    }

    candle_list_t *l = (candle_list_t *)calloc(1, sizeof(candle_list_t));
    *list = l;
    if (l==NULL) {
        return false;
    }
....

和烛台_t 是:


typedef struct {
    uint8_t num_devices;
    candle_err_t last_error;
    candle_device_t dev[CANDLE_MAX_DEVICES];
} candle_list_t;

我转换成


    public struct candle_list_t
    {
        public byte num_devices;
        public candle_err_t last_error;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
        public candle_device_t[] dev;
    }

使用我的第一种方法, num_devices 值有一个值,但它是无效的,因为它超出了 C 库中代码的 num_devices 的限制。使用第二种方法,我只得到一个空结构。

标签: c#cpinvoke

解决方案


推荐阅读