1

I am trying to (for the past 10 hours.... grr) to make this thing work but so far whatever i tried - it refuses :)

Basically i am doing a favor for someone - my strength is not windows / .NET coding for sure and i am trying to patch in some code from something i already have around.

What is the problem?

I am trying to call a C DLL library method returning a 2d array of structs to c#.

But it seems i am doing something wrong regarding in how i read the data from c#.

I've developed a simple C console app and i am calling the DLL from there - all fine - no issues at all. Only the c# fails!

Here is the C implementation of the method:

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

Here is what i am doing in c# side:

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

What is the actual problem?

As soon as i reach the second iteration of the for cycle() i get an access violation:

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

Unhandled exception: Access Violation

I guess i am not calculating the pointer properly but... i really tried a lot of different scenarios and nothing works.

HELP! :)

0

1 Answer 1

1

You are dereferencing p with p = (IntPtr)Marshal.PtrToStructure(p, typeof(IntPtr)); and then at the end when trying to increment, all hell breaks loose.

Use a fresh local so that the original pointer is not continuously dereferenced.

Eg:

 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 :) } 
Sign up to request clarification or add additional context in comments.

8 Comments

I seeee :) But it still goes bad :( Issue 1 is that (p += sSize) does not work - i am on 3.5 sdk - i guess that is the reason - so i've replaced it again with: p = new IntPtr(p.ToInt64() + sSize); The exception now is different: NullReferenceException - again on the 'ppstruct = ...' line. Before it is invoked 'p' has became zero.
Aaand i just solved it :))) I should be doing: p = new IntPtr(p.ToInt64() + IntPtr.Size); instead of: p = new IntPtr(p.ToInt64() + sSize); All perfect now! Thank you BIG!!!!!!
@MartinKovachev: Glad I could help :D p += IntPtr.Size; should work too then
It doesn't recognize the syntax. That's why i reworked it like this in the first place :) the + operation.
I know for sure it works in 4.0 - as i tested it - i guess it's a SDK addon.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.