G
Guest
I am coding a managed C# wrapper for an unmanaged C DLL and I am unable to
marshal a structure that contains an array of structures. When executed, the
following code throws an ArgumentException with a description “Type
ErrorInjectionBuffer can not be marshaled as an unmanaged structure; no
meaningful size or offset can be computed.†I have also included snippets
from the .H file. Any assistance would be greatly appreciated.
[busapi.h] (partial)
#if defined(__WIN32__)
#include <windows.h>
#define CCONV _stdcall
#define NOMANGLE
#endif
#define BT_U16BIT unsigned short
#define BT_U8BIT unsigned char
#define BT_UINT unsigned int
#define BT_INT int
#define EI_COUNT 33 /* Number of error injection words supported by SW */
/* The HW supports one more, for the 33rd data word*/
typedef struct api_eibuf
{
BT_U16BIT buftype; // error injection buffer type
struct
{
BT_U8BIT etype; // error code (e.g. EI_NONE, EI_TWOBUS, etc)
BT_U8BIT edata; // error data (if req'd)
}
error[EI_COUNT];
}
API_EIBUF;
NOMANGLE BT_INT CCONV BusTools_EI_EbufRead(
BT_UINT cardnum, // (i) card number (0 - based)
BT_UINT errorid, // (i) number of error injection buffer to read
API_EIBUF * ebuf); // (o) pointer to resulting buffer values
NOMANGLE BT_INT CCONV BusTools_EI_EbufWrite(
BT_UINT cardnum, // (i) card number (0 - based)
BT_UINT errorid, // (i) number of error injection buffer to write
API_EIBUF * ebuf); // (i) pointer to buffer values to be written to
HW
[C#]
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Class1
{
[DllImport(@"busapi32.dll", EntryPoint = "BusTools_EI_EbufRead")]
public static extern int BusTools_EI_EbufRead(
uint cardnum,
uint errorid,
[MarshalAs(UnmanagedType.LPStruct)]
ref ErrorInjectionBuffer ebuf
);
[DllImport(@"busapi32.dll", EntryPoint = "BusTools_EI_EbufWrite")]
public static extern int BusTools_EI_EbufWrite(
uint cardnum,
uint errorid,
[MarshalAs(UnmanagedType.LPStruct)]
ref ErrorInjectionBuffer ebuf
);
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("SizeOf(struct ErrorInjectionBuffer) = " +
Marshal.SizeOf(typeof(ErrorInjectionBuffer)).ToString()); // Throws
ArgumentException
}
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct ErrorInjectionBuffer
{
private const int ErrorInjectionCount = 33;
private ushort bufferType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ErrorInjectionCount)]
private ErrorInjectionData[] errors;
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct ErrorInjectionData
{
private byte eType;
private byte eData;
}
}
marshal a structure that contains an array of structures. When executed, the
following code throws an ArgumentException with a description “Type
ErrorInjectionBuffer can not be marshaled as an unmanaged structure; no
meaningful size or offset can be computed.†I have also included snippets
from the .H file. Any assistance would be greatly appreciated.
[busapi.h] (partial)
#if defined(__WIN32__)
#include <windows.h>
#define CCONV _stdcall
#define NOMANGLE
#endif
#define BT_U16BIT unsigned short
#define BT_U8BIT unsigned char
#define BT_UINT unsigned int
#define BT_INT int
#define EI_COUNT 33 /* Number of error injection words supported by SW */
/* The HW supports one more, for the 33rd data word*/
typedef struct api_eibuf
{
BT_U16BIT buftype; // error injection buffer type
struct
{
BT_U8BIT etype; // error code (e.g. EI_NONE, EI_TWOBUS, etc)
BT_U8BIT edata; // error data (if req'd)
}
error[EI_COUNT];
}
API_EIBUF;
NOMANGLE BT_INT CCONV BusTools_EI_EbufRead(
BT_UINT cardnum, // (i) card number (0 - based)
BT_UINT errorid, // (i) number of error injection buffer to read
API_EIBUF * ebuf); // (o) pointer to resulting buffer values
NOMANGLE BT_INT CCONV BusTools_EI_EbufWrite(
BT_UINT cardnum, // (i) card number (0 - based)
BT_UINT errorid, // (i) number of error injection buffer to write
API_EIBUF * ebuf); // (i) pointer to buffer values to be written to
HW
[C#]
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Class1
{
[DllImport(@"busapi32.dll", EntryPoint = "BusTools_EI_EbufRead")]
public static extern int BusTools_EI_EbufRead(
uint cardnum,
uint errorid,
[MarshalAs(UnmanagedType.LPStruct)]
ref ErrorInjectionBuffer ebuf
);
[DllImport(@"busapi32.dll", EntryPoint = "BusTools_EI_EbufWrite")]
public static extern int BusTools_EI_EbufWrite(
uint cardnum,
uint errorid,
[MarshalAs(UnmanagedType.LPStruct)]
ref ErrorInjectionBuffer ebuf
);
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("SizeOf(struct ErrorInjectionBuffer) = " +
Marshal.SizeOf(typeof(ErrorInjectionBuffer)).ToString()); // Throws
ArgumentException
}
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct ErrorInjectionBuffer
{
private const int ErrorInjectionCount = 33;
private ushort bufferType;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ErrorInjectionCount)]
private ErrorInjectionData[] errors;
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct ErrorInjectionData
{
private byte eType;
private byte eData;
}
}