tags:

views:

51

answers:

1

Yet another one of my idiotic P/Invoke questions... Sometimes I think this stuff is going to be a piece of cake, but it blows up in my face.

I have a simple unmanaged method that takes a destination array and fills it.

unsigned short NvtlCommon_GetAvailableDevices(SdkHandle session,  
    DeviceDetail * pDev_list, unsigned long * dev_list_size) 

typedef struct
{
    DeviceTechType          eTechnology;
    DeviceFormFactorType    eFormFactor;
    char                    szDescription[NW_MAX_PATH];
    char                    szPort[NW_MAX_PATH];
    char                    szFriendlyName[NW_MAX_PATH];
} DeviceDetail;

I converted these to C#:

[DllImport(NvtlConstants.LIB_CORE, EntryPoint = "NvtlCommon_GetAvailableDevices")]
public static extern NvtlErrorCode GetAvailableDevices(IntPtr session,
    DeviceDetail[] pDev_list, ref long dev_list_size);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DeviceDetail {
    public DeviceTechType eTechnology;
    public DeviceFormFactorType eFormFactor;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NvtlConstants.NW_MAX_PATH)]
    public string szDescription;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NvtlConstants.NW_MAX_PATH)]
    public string szPort;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NvtlConstants.NW_MAX_PATH)]
    public string szFriendlyName;
}

The documentation states that on input, dev_list_size should be the size of the allocated array. On output, it's the number of items that were actually filled. If I use out or ref on the pDev_list argument, my application crashes. This seems to be the only signature that even begins to work.

DeviceDetail[] devices = new DeviceDetail[5];
long count = 5;
GetAvailableDevices(coreHandle, devices, ref count);

That code returns a success message and count is set to 1, which is indeed the number of available devices. However, the array is still 5 uninitialized DeviceDetail structs.

Am I doing something wrong here, or is this a problem with the underlying unmanaged library?

+1  A: 

Have you tried [Out]?

public static extern NvtlErrorCode GetAvailableDevices(IntPtr session,
    [Out] DeviceDetail[] pDev_list, ref long dev_list_size);
      ↑
dtb
Yep, that did it. I knew it would be something simple. Thanks!
David Brown