Interfacing with an API - structs with arrays of structs.

D

Dave A

The following C code specifies the interface into a DLL. I need to access it from C#. How do I do declare it? I have done simple ones before but this particular API requires a pointer to a struct that contains an array of other structs.

typedef struct
{
int nWidth;
int nHeight;
DWORD dwFlags;
} HCA_MODE;

typedef struct
{
DWORD dwSize;
int nCount;
HCA_MODE Mode[16];
} HCA_MODE_INFO;

HRESULT CamPreviewGetModeInfo(HANDLE hCamera,HCA_MODE_INFO *pModeInfo);

This is my attempt...

[StructLayout(LayoutKind.Sequential)]
public struct HCA_MODE
{
int nWidth;
int nHeight;
long dwFlags;
};

[StructLayout(LayoutKind.Sequential)]
public class HCA_MODE_INFO
{
long dwSize; // Size of the structure
int nCount; // Number of modes
HCA_MODE[] Mode = new HCA_MODE[16];
} ;

[DllImport("mobilecamapi.dll",EntryPoint="CamPreviewGetModeInfo")]
public static extern int CamPreviewGetModeInfo(int hCamera, ref HCA_MODE_INFO pModeInfo);

It returns with a 'not supported exception' which I think is a euphemism for you got it the API declaration wrong. I know this API is supported.

Because the struct HCA_MODE_INFO contains a 16 element array I had to declare it as a class in C# since structs don't seem to like having arrays in them. I doubt whether passing a class around is the same as passing a struct.

The documentation seems a little vague about this area. Does anyone know what I am supposed to do?

Also, is a C DWORD a long in C# and a WORD an int?

Regards
Dave A
 
S

Sylvain Lafontaine

Even if they are manipulated as pointers, arrays in C are not pointers: they are arrays and are stored as arrays. You have three solutions: go into unsafe mode and use pointers to allocate the necessary memory, use C++/Managed or try something like this:

typedef struct
{
uint dwSize;
int nCount;

int nWidth0;
int nHeight0;
uint dwFlags0;

int nWidth1;
int nHeight1;
uint dwFlags1;

........

int nWidth15;
int nHeight15;
uint dwFlags15;

} HCA_MODE_INFO;

You will probably find a better way to express this.

DWORD are 32 bits unsigned integer; this is the same thing as « unsigned int » or « unsigned long » in C because both int and long are 32 bits in C but in C#, this is an « uint » or System.UInt32; not a long. Long in C# are 64 bits. WORD are 16 bits or « ushort » or System.UInt16.

S. L.
The following C code specifies the interface into a DLL. I need to access it from C#. How do I do declare it? I have done simple ones before but this particular API requires a pointer to a struct that contains an array of other structs.

typedef struct
{
int nWidth;
int nHeight;
DWORD dwFlags;
} HCA_MODE;

typedef struct
{
DWORD dwSize;
int nCount;
HCA_MODE Mode[16];
} HCA_MODE_INFO;

HRESULT CamPreviewGetModeInfo(HANDLE hCamera,HCA_MODE_INFO *pModeInfo);

This is my attempt...

[StructLayout(LayoutKind.Sequential)]
public struct HCA_MODE
{
int nWidth;
int nHeight;
long dwFlags;
};

[StructLayout(LayoutKind.Sequential)]
public class HCA_MODE_INFO
{
long dwSize; // Size of the structure
int nCount; // Number of modes
HCA_MODE[] Mode = new HCA_MODE[16];
} ;

[DllImport("mobilecamapi.dll",EntryPoint="CamPreviewGetModeInfo")]
public static extern int CamPreviewGetModeInfo(int hCamera, ref HCA_MODE_INFO pModeInfo);

It returns with a 'not supported exception' which I think is a euphemism for you got it the API declaration wrong. I know this API is supported.

Because the struct HCA_MODE_INFO contains a 16 element array I had to declare it as a class in C# since structs don't seem to like having arrays in them. I doubt whether passing a class around is the same as passing a struct.

The documentation seems a little vague about this area. Does anyone know what I am supposed to do?

Also, is a C DWORD a long in C# and a WORD an int?

Regards
Dave A
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top