如何从C#P / Invoke

时间:2019-07-09 19:18:39

标签: c# c pinvoke

我正在尝试围绕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;
    }
....

和Candle_list_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个设备的限制。使用第二种方法,我得到的是一个空结构。

0 个答案:

没有答案