gpt4 book ai didi

c# - 将 C 结构数组编码为 C#

转载 作者:太空宇宙 更新时间:2023-11-04 03:41:36 24 4
gpt4 key购买 nike

我正在努力(在过去的 10 个小时里......grr)让这个东西工作,但到目前为止无论我尝试了什么 - 它都拒绝了:)

基本上,我是在帮某人一个忙——我的长处肯定不是 Windows/.NET 编码,我正在尝试从我已有的东西中修补一些代码。

问题是什么?

我正在尝试调用一个 C DLL 库方法,将一个二维结构数组返回给 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;}

这是我在 C# 端所做的:

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

实际问题是什么?

一旦我到达 for cycle() 的第二次迭代,我就会遇到访问冲突:

An unhandled exception of type 'System.AccessViolationException' occurred in mscorlib.dll

Unhandled exception: Access Violation

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

帮助! :)

最佳答案

您正在使用 p = (IntPtr)Marshal.PtrToStructure(p, typeof(IntPtr)); 取消对 p 的引用,然后在最后尝试递增时,所有 hell 破灭了。

使用一个新的本地指针,这样原始指针就不会被连续取消引用。

例如:

    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 :)
}

关于c# - 将 C 结构数组编码为 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27982403/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com