[Mono-dev] libmtp bindings

Ted Bullock tbullock at canada.com
Fri Jan 19 02:11:36 EST 2007


Ok, I am still having a bit of trouble here.  The double indirection
thing is pretty confusing when trying to deal with it across the
unmanaged/managed barriers.

Here is the original c structure.  It is pretty straightforward.

struct device_entry_struct {
  char *name;
  uint16_t vendor_id;
  uint16_t product_id;
  uint32_t device_flags;
};

Normally an array of pointers to this structure is generated as a list
of devices that libmtp supports.  This list is statically defined within
the library itself.

Programs that link to this library can access this list through the
following function, again notice the const:

void Get_Supported_Devices(device_entry_t ** const, int * const);

So I have the following C# code to wrap this.  Note that this code
*does* run when I test it, however the results are *incorrect*

[StructLayout(LayoutKind.Sequential)]
public class DeviceEntry
{
  private IntPtr name;
  private ushort vendor_id;
  private ushort product_id;
  private uint device_flags;
	
[DllImport ("libmtp")]
internal static extern void Get_Supported_Devices(
	out IntPtr devicelist,
	out int NumDevices);
	
public static DeviceEntry[] SupportedDeviceList()
{
IntPtr DeviceList;
int NumDevices;

Get_Supported_Devices(out DeviceList, out NumDevices);
		
if (NumDevices <= 0)
  return new DeviceEntry[]{};

DeviceEntry[] Devices = new DeviceEntry[NumDevices];
		
for (int i = 0; i < NumDevices; ++i)
{
  IntPtr s = Marshal.ReadIntPtr(DeviceList, i *
	Marshal.SizeOf(typeof(DeviceEntry)));
  Devices[i] = (DeviceEntry)Marshal.PtrToStructure(s,
	typeof(DeviceEntry));
}
		
return Devices;
}

}

Then I have a small Main function to test with.  However the product
IDs, Vendor IDs are not the same as the ones listed in the libmtp
library itself. :(  and executing the Device.GetDeviceName() causes the
program to die.

public static void Main(string[] args)
{

DeviceEntry[] DeviceList = SupportedDeviceList();
		
Console.WriteLine("Number of Supported Devices " + DeviceList.Length);
		
foreach(DeviceEntry Device in DeviceList) {
  Console.Write("Product Id: " + Device.GetProductID())
  Console.WriteLine(" Vendor Id: " + Device.GetVendorID());

  // Crashes on the following line
  Console.WriteLine("Device Name: " + Device.GetDeviceName());
  }
}

Lastly a couple of GET methods

public ushort GetVendorID()
{
  return vendor_id;
}
	
public ushort GetProductID()
{
  return product_id;
}
	
public uint GetDeviceFlags()
{
  return device_flags;
}
	
public string GetDeviceName()
{
  if(name == IntPtr.Zero)
    return "Unknown Device";

  return Marshal.PtrToStringAuto(name);
}


Sorry for the long email. I suppose that I could attach this as an
extension.  Anyways, I am very frustrated with this since I have been
working on it for most of the day with almost no progress whatsoever.

-Ted



More information about the Mono-devel-list mailing list