469,657 Members | 1,819 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,657 developers. It's quick & easy.

Passing an array of structs to unmanaged dll

Hi, I have a C# program that uses an unmanaged dll that has a function
similar to the signature below :

void f(out MyStruct[] arr, out int num); // num = actual array length returned

The array must be allocated (with known max length = 10) before the call to
the dll function (the dll just fills it ,with no allocations).

The definitions of Mystruct and :
public struct Mystruct TimeTag
{
Int32 Id;
Int32 Type;
TimeTag StartTime;
TimeTag EndTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
Int32[] Reserved;
}

public struct TimeTag
{
int Day;
Int Hour;
}
I allocate the array , init all fields , allocate and init all needed struct
fields , pass it to the dll and get an exception:

"The runtime has encountered a fatal error. The address of the error was at
0x79e95b95, on thread 0x28348. The error code is 0xc0000005. This error may
be a bug in the CLR or in the unsafe or non-verifiable portions of user code.
Common sources of this bug include user marshaling errors for COM-interop or
PInvoke, which may corrupt the stack".

I can't change nor the dll neither it's API.

What is the problem and what should I do to avoid it?
Nov 11 '07 #1
6 8743
Alexanderfe,

Can you give the original function and structure declaration in C? The
reason I ask is because I want to know if the Reserved field on the MyStruct
structure is embedded in the structure, or a pointer to another array.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Alexanderfe" <Al*********@discussions.microsoft.comwrote in message
news:36**********************************@microsof t.com...
Hi, I have a C# program that uses an unmanaged dll that has a function
similar to the signature below :

void f(out MyStruct[] arr, out int num); // num = actual array length
returned

The array must be allocated (with known max length = 10) before the call
to
the dll function (the dll just fills it ,with no allocations).

The definitions of Mystruct and :
public struct Mystruct TimeTag
{
Int32 Id;
Int32 Type;
TimeTag StartTime;
TimeTag EndTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
Int32[] Reserved;
}

public struct TimeTag
{
int Day;
Int Hour;
}
I allocate the array , init all fields , allocate and init all needed
struct
fields , pass it to the dll and get an exception:

"The runtime has encountered a fatal error. The address of the error was
at
0x79e95b95, on thread 0x28348. The error code is 0xc0000005. This error
may
be a bug in the CLR or in the unsafe or non-verifiable portions of user
code.
Common sources of this bug include user marshaling errors for COM-interop
or
PInvoke, which may corrupt the stack".

I can't change nor the dll neither it's API.

What is the problem and what should I do to avoid it?
Nov 11 '07 #2
Thanks for the reply,
It's embedded

typedef struct Mystruct{
LONGINT Id;
LONGINT Type;
TimeTag StartTime;
TimeTag EndTime;
LONGINT Reserved[2];
};

"Nicholas Paldino [.NET/C# MVP]" wrote:
Alexanderfe,

Can you give the original function and structure declaration in C? The
reason I ask is because I want to know if the Reserved field on the MyStruct
structure is embedded in the structure, or a pointer to another array.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Alexanderfe" <Al*********@discussions.microsoft.comwrote in message
news:36**********************************@microsof t.com...
Hi, I have a C# program that uses an unmanaged dll that has a function
similar to the signature below :

void f(out MyStruct[] arr, out int num); // num = actual array length
returned

The array must be allocated (with known max length = 10) before the call
to
the dll function (the dll just fills it ,with no allocations).

The definitions of Mystruct and :
public struct Mystruct TimeTag
{
Int32 Id;
Int32 Type;
TimeTag StartTime;
TimeTag EndTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
Int32[] Reserved;
}

public struct TimeTag
{
int Day;
Int Hour;
}
I allocate the array , init all fields , allocate and init all needed
struct
fields , pass it to the dll and get an exception:

"The runtime has encountered a fatal error. The address of the error was
at
0x79e95b95, on thread 0x28348. The error code is 0xc0000005. This error
may
be a bug in the CLR or in the unsafe or non-verifiable portions of user
code.
Common sources of this bug include user marshaling errors for COM-interop
or
PInvoke, which may corrupt the stack".

I can't change nor the dll neither it's API.

What is the problem and what should I do to avoid it?
Nov 11 '07 #3
I've forgot to mention that when I use structs that consist only of Int32
fields in the same manor, all works fine and no exception is thrown.

"Nicholas Paldino [.NET/C# MVP]" wrote:
Alexanderfe,

Can you give the original function and structure declaration in C? The
reason I ask is because I want to know if the Reserved field on the MyStruct
structure is embedded in the structure, or a pointer to another array.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Alexanderfe" <Al*********@discussions.microsoft.comwrote in message
news:36**********************************@microsof t.com...
Hi, I have a C# program that uses an unmanaged dll that has a function
similar to the signature below :

void f(out MyStruct[] arr, out int num); // num = actual array length
returned

The array must be allocated (with known max length = 10) before the call
to
the dll function (the dll just fills it ,with no allocations).

The definitions of Mystruct and :
public struct Mystruct TimeTag
{
Int32 Id;
Int32 Type;
TimeTag StartTime;
TimeTag EndTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
Int32[] Reserved;
}

public struct TimeTag
{
int Day;
Int Hour;
}
I allocate the array , init all fields , allocate and init all needed
struct
fields , pass it to the dll and get an exception:

"The runtime has encountered a fatal error. The address of the error was
at
0x79e95b95, on thread 0x28348. The error code is 0xc0000005. This error
may
be a bug in the CLR or in the unsafe or non-verifiable portions of user
code.
Common sources of this bug include user marshaling errors for COM-interop
or
PInvoke, which may corrupt the stack".

I can't change nor the dll neither it's API.

What is the problem and what should I do to avoid it?
Nov 11 '07 #4
"Alexanderfe" <Al*********@discussions.microsoft.comwrote in message
news:36**********************************@microsof t.com...
Hi, I have a C# program that uses an unmanaged dll that has a function
similar to the signature below :

void f(out MyStruct[] arr, out int num); // num = actual array length
returned

The array must be allocated (with known max length = 10) before the call
to
the dll function (the dll just fills it ,with no allocations).

The definitions of Mystruct and :
public struct Mystruct TimeTag
{
Int32 Id;
Int32 Type;
TimeTag StartTime;
TimeTag EndTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
Int32[] Reserved;
}

public struct TimeTag
{
int Day;
Int Hour;
}
I allocate the array , init all fields , allocate and init all needed
struct
fields , pass it to the dll and get an exception:

"The runtime has encountered a fatal error. The address of the error was
at
0x79e95b95, on thread 0x28348. The error code is 0xc0000005. This error
may
be a bug in the CLR or in the unsafe or non-verifiable portions of user
code.
Common sources of this bug include user marshaling errors for COM-interop
or
PInvoke, which may corrupt the stack".

I can't change nor the dll neither it's API.

What is the problem and what should I do to avoid it?


The caller allocates the array of structs, however, you pass it as "out
MyStruct[]", this ain't gonna work, by this you are expecting the callee to
create the struct array and pass a pointer back to the caller (what you
effectively pass is a null pointer). You need to pass your struct array by
ref.

f(ref MyStruct[] arr, out int num);

....
int num = 0;
MyStruct[] ms = new MyStruct[10]; // allocate array of structs
f(ref ms, out int num); // pass the array address, callee fills the array
...

Willy.

Nov 11 '07 #5
Alexanderfe,

Given that, your structure declarations should look like this:

[StructLayout(LayoutKind.Sequential)]
public struct TimeTag
{
public int Day;
public int Hour;
}

[StructLayout(LayoutKind.Sequential)]
public struct Mystruct
{
public int Id;
public int Type;
public TimeTag StartTime;
public TimeTag EndTime;
public fixed int Reserved[2];
}

Notice the fixed keyword on the array field in the Mystruct declaration.
This causes the array to be embedded in the struct, and not a pointer to the
array. This is why it works when you declare two separate integers in the
struct, because the layout in memory is the same (one integer after
another).

Also note Willy's comments as well.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

LONGINT Id;
LONGINT Type;
TimeTag StartTime;
TimeTag EndTime;
LONGINT Reserved[2];
};
"Alexanderfe" <Al*********@discussions.microsoft.comwrote in message
news:B1**********************************@microsof t.com...
Thanks for the reply,
It's embedded

typedef struct Mystruct{
LONGINT Id;
LONGINT Type;
TimeTag StartTime;
TimeTag EndTime;
LONGINT Reserved[2];
};

"Nicholas Paldino [.NET/C# MVP]" wrote:
>Alexanderfe,

Can you give the original function and structure declaration in C?
The
reason I ask is because I want to know if the Reserved field on the
MyStruct
structure is embedded in the structure, or a pointer to another array.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Alexanderfe" <Al*********@discussions.microsoft.comwrote in message
news:36**********************************@microso ft.com...
Hi, I have a C# program that uses an unmanaged dll that has a function
similar to the signature below :

void f(out MyStruct[] arr, out int num); // num = actual array length
returned

The array must be allocated (with known max length = 10) before the
call
to
the dll function (the dll just fills it ,with no allocations).

The definitions of Mystruct and :
public struct Mystruct TimeTag
{
Int32 Id;
Int32 Type;
TimeTag StartTime;
TimeTag EndTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
Int32[] Reserved;
}

public struct TimeTag
{
int Day;
Int Hour;
}
I allocate the array , init all fields , allocate and init all needed
struct
fields , pass it to the dll and get an exception:

"The runtime has encountered a fatal error. The address of the error
was
at
0x79e95b95, on thread 0x28348. The error code is 0xc0000005. This error
may
be a bug in the CLR or in the unsafe or non-verifiable portions of user
code.
Common sources of this bug include user marshaling errors for
COM-interop
or
PInvoke, which may corrupt the stack".

I can't change nor the dll neither it's API.

What is the problem and what should I do to avoid it?
Nov 11 '07 #6
Marshaling arrays of structs is problematic (unless they are holding
blit-able types only) in .NET, so you'll have to take care about the
marshaling yourself.
Basically what you need to do is pass the struct array as an array of
IntPtr's each pointing to an unmanaged struct, on return from unmanaged code
you'll have to marshal the IntPtr's back to their managed struct
representation.

Following illustrates the process.

// C function, takes a pointer to a pointer of type MyStruct and a ref int
holding the size of the input array
extern "C" void __declspec(dllexport) __stdcall F(Mystruct **p, int &size)
{
int n;
Mystruct * ps;
for(int n = 0; n < size; n++)
{
ps = *p++;
//set the struct fields using pointer arithmetics
ps->Id = 1;
..
}
size = n;
}
// C# snip

...
[StructLayout(LayoutKind.Sequential)]
public struct TimeTag
{
public int Day;
public int Hour;
}

[StructLayout(LayoutKind.Sequential)]
public struct Mystruct
{
public int Id;
public int Type;
public TimeTag StartTime;
public TimeTag EndTime;
public fixed int Reserved[2];
}
....
[DllImport("dllname"), SuppressUnmanagedCodeSecurity] static extern void
F( IntPtr[] p, ref int size);
....
int size = 10;
IntPtr[] ps = new IntPtr[size ];
for(int n = 0; n <size ; n++)
ps[n] =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Mystruc t )));
GetEmbeddedArray2(ps2, ref size );
Mystruct [] s = new Mystruct [size];
for(int i = 0; i < size ; i++)
s[i] = (Mystruct )Marshal.PtrToStructure(ps[i],
typeof(Mystruct ));

// use array of structs here...
....

Willy.
"Alexanderfe" <Al*********@discussions.microsoft.comwrote in message
news:15**********************************@microsof t.com...
I've forgot to mention that when I use structs that consist only of Int32
fields in the same manor, all works fine and no exception is thrown.

"Nicholas Paldino [.NET/C# MVP]" wrote:
>Alexanderfe,

Can you give the original function and structure declaration in C?
The
reason I ask is because I want to know if the Reserved field on the
MyStruct
structure is embedded in the structure, or a pointer to another array.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Alexanderfe" <Al*********@discussions.microsoft.comwrote in message
news:36**********************************@microso ft.com...
Hi, I have a C# program that uses an unmanaged dll that has a function
similar to the signature below :

void f(out MyStruct[] arr, out int num); // num = actual array length
returned

The array must be allocated (with known max length = 10) before the
call
to
the dll function (the dll just fills it ,with no allocations).

The definitions of Mystruct and :
public struct Mystruct TimeTag
{
Int32 Id;
Int32 Type;
TimeTag StartTime;
TimeTag EndTime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
Int32[] Reserved;
}

public struct TimeTag
{
int Day;
Int Hour;
}
I allocate the array , init all fields , allocate and init all needed
struct
fields , pass it to the dll and get an exception:

"The runtime has encountered a fatal error. The address of the error
was
at
0x79e95b95, on thread 0x28348. The error code is 0xc0000005. This error
may
be a bug in the CLR or in the unsafe or non-verifiable portions of user
code.
Common sources of this bug include user marshaling errors for
COM-interop
or
PInvoke, which may corrupt the stack".

I can't change nor the dll neither it's API.

What is the problem and what should I do to avoid it?

Nov 11 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Raju V.K | last post: by
2 posts views Thread by Claire | last post: by
1 post views Thread by Steve Baer | last post: by
17 posts views Thread by mr.resistor | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.