[Mono-devel-list] Problems calling unmanaged code

Ewen Cheslack-Postava echeslack at gmail.com
Sun Aug 1 12:48:29 EDT 2004


Hi all,

I am having some trouble calling unmanaged code.  I am writing
bindings for libgphoto2 and have made some progress.  Many of the
functions are working fine.

However, when I try to call a function that requires a pointer to a
struct to be passed in my process is getting killed.  I think I must
have a problem with the size of the struct or something because all
that is in the function is a memcpy.

The unmanaged code looks like this:

int
gp_abilities_list_get_abilities (CameraAbilitiesList *list, int index,
				 CameraAbilities *abilities)
{
	CHECK_NULL (list && abilities);

	if (index < 0 || index >= list->count)
		return (GP_ERROR_BAD_PARAMETERS);

	memcpy (abilities, &list->abilities[index], sizeof (CameraAbilities));

	return (GP_OK);
}

The CameraAbilities struct looks like this in unmanaged code:

typedef struct {
        char model [128];
        CameraDriverStatus status;

        /* Supported ports and speeds (latter terminated with a value of 0) */
        GPPortType port;
        int speed [64];

        /* Supported operations */
        CameraOperation       operations;
        CameraFileOperation   file_operations;
        CameraFolderOperation folder_operations;

        int usb_vendor, usb_product;
        int usb_class, usb_subclass, usb_protocol;

        /* For core use */
        char library [1024];
        char id [1024];

		/* Reserved space to use in the future w/out changing the struct size */
        int reserved1;
        int reserved2;
        int reserved3;
        int reserved4;
        int reserved5;
        int reserved6;
        int reserved7;
        int reserved8;
} CameraAbilities;

(The types that are not obvious are all enums)

which I translated to this:

[StructLayout(LayoutKind.Sequential)]
	public unsafe struct _CameraAbilities
	{
		[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] string model;
		_CameraDriverStatus status;
		
		_GPPortType port;
		[MarshalAs(UnmanagedType.ByValArray, SizeConst=64)] int[] speed;
		
		_CameraOperation operations;
		_CameraFileOperation file_operations;
		_CameraFolderOperation folder_operations;
		
		int usb_vendor;
		int usb_product;
		int usb_class;
		int usb_subclass;
		int usb_protocol;
		
		[MarshalAs(UnmanagedType.ByValTStr, SizeConst=1024)] string library;
		[MarshalAs(UnmanagedType.ByValTStr, SizeConst=1024)] string id;
		
		int reserved1;
		int reserved2;
		int reserved3;
		int reserved4;
		int reserved5;
		int reserved6;
		int reserved7;
		int reserved8;
	}

The function prototype I have in my bindings looks like this:

		[DllImport ("libgphoto2.so")]
		internal static extern int gp_abilities_list_get_abilities
(_CameraAbilitiesList *list, int index, _CameraAbilities *abilities);


And I use code like this to call it:


int result;
_CameraAbilities abilities = new _CameraAbilities();
unsafe
{
	result = _CameraAbilitiesList.gp_abilities_list_get_abilities(obj,
index, &abilities);
}
if (result < 0) throw new Exception(); //FIXME
return abilities;


And it gets killed.  I can only see two possible problems:

1) I translated the struct incorrectly.  But my other structs have
worked so far.
2) I am only having problems with struct types that are not allocated
by the native library.  i.e., when I use pointers to structures and
can allocate them with gp_struct_type_new(ptr_ptr_to_struct); then
everything is ok.  If the managed code allocates it then it gets
killed when it is used.

This is my first time using InteropServices so I may be missing
something really obvious.

Sorry abou the long mail.

Ewen Cheslack-Postava



More information about the Mono-devel-list mailing list