[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