将结构的C数组封送到C#

将结构的C数组封送到C#,c#,c,dll,marshalling,C#,C,Dll,Marshalling,我正在努力(在过去的10个小时里……grr)使这件事起作用,但到目前为止,无论我尝试了什么,它都拒绝了:) 基本上,我是在帮某人的忙——我的优势肯定不是windows/.NET编码,我正在尝试从我已经有的东西中插入一些代码 有什么问题 我试图调用一个C DLL库方法,将结构的2d数组返回给C# 但是我在如何从c#读取数据方面似乎做错了什么 我已经开发了一个简单的C控制台应用程序,我正在从那里调用DLL-一切正常-没有任何问题。只有c#失败了 下面是该方法的C实现: int get_availab

我正在努力(在过去的10个小时里……grr)使这件事起作用,但到目前为止,无论我尝试了什么,它都拒绝了:)

基本上,我是在帮某人的忙——我的优势肯定不是windows/.NET编码,我正在尝试从我已经有的东西中插入一些代码

有什么问题

我试图调用一个C DLL库方法,将结构的2d数组返回给C#

但是我在如何从c#读取数据方面似乎做错了什么

我已经开发了一个简单的C控制台应用程序,我正在从那里调用DLL-一切正常-没有任何问题。只有c#失败了

下面是该方法的C实现:

int get_available_devices(idevice_info_t **devices, uint32_t *count) {
char **dev_list = NULL;
char *dev_name = NULL;
int i, total_devices;

if (idevice_get_device_list(&dev_list, &total_devices) < 0) {
    fprintf(stderr, "ERROR: Unable to retrieve device list!\n");
    return -1;
}

idevice_info_t *tmpArr = (idevice_info_t*)calloc(total_devices, sizeof(idevice_info));

int ii = 0;
int res_name = 0;

idevice_info_t dtmp = NULL;

for (i = 0; i <= total_devices - 1; i++) {
    res_name = idevice_get_device_name(dev_list[i], &dev_name);
    dev_name = (res_name == 0 ? dev_name : "");

    printf("%s: %s\n", dev_name, dev_list[i]);

    dtmp = (idevice_info_t)malloc(sizeof(struct idevice_info));
    strncpy_s(dtmp->udid, sizeof dtmp->udid - 1, dev_list[i], sizeof dtmp->udid - 1);
    strncpy_s(dtmp->name, sizeof dtmp->name - 1, dev_name, sizeof dtmp->name - 1);
    tmpArr[i] = dtmp;
}
idevice_device_list_free(dev_list);

*devices = tmpArr;
*count = total_devices;

return 0;}

我想我没有正确计算指针,但是。。。我真的尝试了很多不同的场景,但都没有效果


救命!:)

您正在使用
p=(IntPtr)Marshal.PtrToStructure(p,typeof(IntPtr))解除对
p
的引用然后在最后,当尝试增加时,所有的地狱都松开了

使用新的本地指针,以便原始指针不会连续取消引用

例如:


for(int i=0;i i i seeee:)但它仍然很糟糕:(问题1是(p+=sSize)不起作用-我使用的是3.5 sdk-我想这就是原因-因此我再次将其替换为:p=new IntPtr(p.ToInt64()+sSize);异常现在不同了:NullReferenceException-再次出现在“ppstruct=…”行上。在调用之前,“p”已变为零。aa我刚刚解决了它:))我应该做:p=new IntPtr(p.ToInt64()+IntPtr.Size);而不是:p=newintptr(p.ToInt64()+sSize);现在一切都完美了!谢谢你大@马丁科瓦切夫:很高兴我能帮忙:D
p+=IntPtr.Size
也应该起作用,但它无法识别语法。这就是为什么我一开始就对它进行了这样的修改:)这个+操作。我确信它在4.0中可以工作——正如我测试的那样——我猜它是一个SDK插件。
[DllImport(LIBNAME, CallingConvention = CallingConvention.Cdecl)]
    static public extern short get_available_devices(out IntPtr devices, out uint count);

public static Dictionary<string, string> getAvailableDevices()
    {
        IntPtr p = IntPtr.Zero;
        Dictionary<string, string> ret = null;

        uint totalDevices = 0;

        int res = External.get_available_devices(out p, out totalDevices);

        if (res != 0 || totalDevices < 1)
        {
            return null;
        }

        ret = new Dictionary<string, string>();

        External.idevice_info ppStruct;
        int sSize = Marshal.SizeOf(typeof(External.idevice_info));

        for (int i = 0; i <= totalDevices - 1; i++)
        {
            p = (IntPtr)Marshal.PtrToStructure(p, typeof(IntPtr));
            ppStruct = (External.idevice_info)Marshal.PtrToStructure(p, typeof(External.idevice_info));

            ret.Add(ppStruct.udid, ppStruct.name);

            p = new IntPtr(p.ToInt64() + sSize);
        }

        return ret;
    }
An unhandled exception of type 'System.AccessViolationException' occurred in mscorlib.dll
    for (int i = 0; i <= totalDevices - 1; i++)
    {
        IntPtr pp = (IntPtr)Marshal.PtrToStructure(p, typeof(IntPtr));
        ppStruct = (External.idevice_info)Marshal.PtrToStructure(pp, 
                      typeof(External.idevice_info));

        ret.Add(ppStruct.udid, ppStruct.name);

        p += sSize; // easier, does the same :)
    }