DllImport - Function use as parameter an array of structures

M

McKool

Hello everybody. I have a problem importing a function from a Dll. This dll was made in C++. I get in troubles when I try to use the following function:

Function
DLL DWORD __stdcall ReadWithArray(
byte MyByte,
TStruct* pStruct,
long nMaxStructCount,
long* pStructReadCount);
C# [DllImport("MyDll.dll", EntryPoint="ReadArray")]
public static extern uint ReadWithArray(
byte MyByte,
TSruct[] pStruct,
long nMaxStructCount,
out long pStructReadCount);


Here are also the structures; mabe come the problem from here too.

structures:
DLL typedef struct
{
TS1 MyS1;
byte MyByte;
TS2 MyS2;
} TStruct; typedef struct
{
DWORD DW;
BYTE BYTE1;
BYTE BYTE2;
BYTE BYTES[8];
} TS1; typedef struct
{
DWORD DW;
WORD W1;
WORD W2;
} TS2;

C# [StructLayout(LayoutKind.Sequential)]
public struct TSruct
{
public TS MyS1;
public byte MyByte;
public TS2 MyS2;
} [StructLayout(LayoutKind.Sequential)]
public struct TS1
{
public uint DW;
public byte BYTE1;
public byte BYTE2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] BYTES;
} [StructLayout(LayoutKind.Sequential)]
public struct TS2
{
public uint DW;
public ushort B1;
public ushort B2;
}


/-----------------------------------------------------------------------------------------------------------
I don't know if the problem is the memory allocation for the array of my TStruct but is the only thing which I didn't made before (a pointer to an arrray in an imported function). Should I make some Marshaling?? (i have seen some examples about that but I'm not sure of I have to do something like that in my case).

TStruct[] Buffer;
int iREadCount, iCount = 10;
byte MyByte;

Buffer= new TStruct[iCount];
for(int i= 0; i < iCount; i++)
Buffer.MyS1.BYTES = new byte[8];

///---- and here come the error!!! ----///
//
ecRes = ReadWithArray(MyByte,Buffer,iCount,out iReadCount);


I will appreciate all the information about this.
Many Thanks in advance

/-----------------------------------------------------------------------------------------------------------

KW
 
M

Mattias Sjögren

C# [DllImport("MyDll.dll", EntryPoint="ReadArray")]
public static extern uint ReadWithArray(
byte MyByte,
TSruct[] pStruct,
long nMaxStructCount,
out long pStructReadCount);

Change the longs to ints. You may also have to add the [Out] attribute
to the array parameter for it to be marshaled back correctly.


Mattias
 
M

McKool

Thanks a lot!

Mattias Sjögren said:
C# [DllImport("MyDll.dll", EntryPoint="ReadArray")]
public static extern uint ReadWithArray(
byte MyByte,
TSruct[] pStruct,
long nMaxStructCount,
out long pStructReadCount);

Change the longs to ints. You may also have to add the [Out] attribute
to the array parameter for it to be marshaled back correctly.


Mattias
 
M

McKool

Hello Mattias,

with the changes it works. But now the problem is the data. When I
receive a couple of data in the array, only is correct the first item, the
rest is not Ok, there are missing values or random dada and even invalid
data....
by example... the function return a value of 10 (ten structures read) and
when I try to index after the 7, I get on a Out of Index problem....

any Idea?.

Thanks Again.

Mattias Sjögren said:
C# [DllImport("MyDll.dll", EntryPoint="ReadArray")]
public static extern uint ReadWithArray(
byte MyByte,
TSruct[] pStruct,
long nMaxStructCount,
out long pStructReadCount);

Change the longs to ints. You may also have to add the [Out] attribute
to the array parameter for it to be marshaled back correctly.


Mattias
 
M

McKool

I have already found the problem... I add the Attribute [Pack=1] in my
structure definition
[StructLayout(LayoutKind.Sequential,Pack=1)].

Thanks Again.

Mattias Sjögren said:
C# [DllImport("MyDll.dll", EntryPoint="ReadArray")]
public static extern uint ReadWithArray(
byte MyByte,
TSruct[] pStruct,
long nMaxStructCount,
out long pStructReadCount);

Change the longs to ints. You may also have to add the [Out] attribute
to the array parameter for it to be marshaled back correctly.


Mattias
 

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