471,354 Members | 1,549 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,354 software developers and data experts.

passing array of structs to unmanaged code

Using .NET 3.5, I need to pass an array of structs as parameter to a C++
unmanaged function.

The C++ dll stores some data in an unmanaged cache, the function writes
the values into the array of structs. The array of structs are allocated
by C#.

If I pass the array without 'ref' it works fine on the C++ side, but
after returning to C# the array struct values are all zero. If I pass
with 'ref' the application crashes. If I use a class instead of a
struct, the application crashes as well. The struct array I am passing
is an array of:
System.Drawing.PointF

Also, note that the structs passed not in an array work and the values
are updated.

Here is some code:

C++:

void WINAPI GeomBoolGetPgon(const PgonBoolRec & pbr, int i, Point2Rec *
p, int & n)
{
int j;

if ((i < 0) || (i pbr.np))
{
n = -1;
return;
}
n = pbr.pPgon[i].n;
for (j = 0; j <= n; j++)
p[j] = pbr.pPt[pbr.pPgon[i].ndx + j];
}
C#
[DllImport("xform300.dll", EntryPoint = "GeomBoolGetPgon")]
public static extern void BoolGetPgon(PgonBoolRec pbr, int i, PointF[]
pg, out int n);
List<Polygon2FDoBooleanOp(BooleanType bt, Polygon2F pgon, float tol,
float faraway)
{
List<Polygon2Fpgons = new List<Polygon2F>();

Geom.PgonBoolRec pbr = new Geom.PgonBoolRec();

int i = 0;
PointF[] pg1 = new PointF[pgon.Points.Count];
foreach (Point2F pt in pgon.Points)
pg1[i++] = new PointF(pt.X, pt.Y);
i = 0;
PointF[] pg2 = new PointF[_pts.Count];
foreach (Point2F pt in _pts)
pg2[i++] = new PointF(pt.X, pt.Y);

try
{
int btype = (int)bt;
int n = pbr.maxN;
int ret = Geom.BoolPgonPgon(btype, pg1, pg1.Length, pg2, pg2.Length, pbr);
if ((pbr.np -1) && (ret == 0))
{
PointF[] pg = new PointF[pbr.maxN];
for (i = 0; i < pbr.maxN; ++i)
pg[i] = new PointF();

for (i = 0; i <= pbr.np; ++i)
{
n = pbr.maxN;
Geom.BoolGetPgon(pbr, i, pg, out n);
pgons.Add(new Polygon2F(pg));
}
}
}
finally
{
Geom.BoolCleanup(pbr);
}

return pgons;
}
Jun 27 '08 #1
2 4240
Please note, in the code below PgonBoolRec is a class, if I change it to
a struct and pass by 'ref' it works as well, although the array of
PointF structs still returns zeroed values.

Thanks for any help.
jonpb wrote:
Using .NET 3.5, I need to pass an array of structs as parameter to a C++
unmanaged function.

The C++ dll stores some data in an unmanaged cache, the function writes
the values into the array of structs. The array of structs are allocated
by C#.

If I pass the array without 'ref' it works fine on the C++ side, but
after returning to C# the array struct values are all zero. If I pass
with 'ref' the application crashes. If I use a class instead of a
struct, the application crashes as well. The struct array I am passing
is an array of:
System.Drawing.PointF

Also, note that the structs passed not in an array work and the values
are updated.

Here is some code:

C++:

void WINAPI GeomBoolGetPgon(const PgonBoolRec & pbr, int i, Point2Rec *
p, int & n)
{
int j;

if ((i < 0) || (i pbr.np))
{
n = -1;
return;
}
n = pbr.pPgon[i].n;
for (j = 0; j <= n; j++)
p[j] = pbr.pPt[pbr.pPgon[i].ndx + j];
}
C#
[DllImport("xform300.dll", EntryPoint = "GeomBoolGetPgon")]
public static extern void BoolGetPgon(PgonBoolRec pbr, int i, PointF[]
pg, out int n);
List<Polygon2FDoBooleanOp(BooleanType bt, Polygon2F pgon, float tol,
float faraway)
{
List<Polygon2Fpgons = new List<Polygon2F>();

Geom.PgonBoolRec pbr = new Geom.PgonBoolRec();

int i = 0;
PointF[] pg1 = new PointF[pgon.Points.Count];
foreach (Point2F pt in pgon.Points)
pg1[i++] = new PointF(pt.X, pt.Y);
i = 0;
PointF[] pg2 = new PointF[_pts.Count];
foreach (Point2F pt in _pts)
pg2[i++] = new PointF(pt.X, pt.Y);

try
{
int btype = (int)bt;
int n = pbr.maxN;
int ret = Geom.BoolPgonPgon(btype, pg1, pg1.Length, pg2,
pg2.Length, pbr);
if ((pbr.np -1) && (ret == 0))
{
PointF[] pg = new PointF[pbr.maxN];
for (i = 0; i < pbr.maxN; ++i)
pg[i] = new PointF();

for (i = 0; i <= pbr.np; ++i)
{
n = pbr.maxN;
Geom.BoolGetPgon(pbr, i, pg, out n);
pgons.Add(new Polygon2F(pg));
}
}
}
finally
{
Geom.BoolCleanup(pbr);
}

return pgons;
}
Jun 27 '08 #2
jonpb wrote:
Using .NET 3.5, I need to pass an array of structs as parameter to a C++
unmanaged function.
I tried using ref IntPtr and using Marshal.AllocCoTaskMem etc. but again
that crashed the program. I finally got it to work by adding [In, Out]
to the parameter signature.

While, I'm glad it is now working, from what I can tell from the MSDN
site, this is not the correct way to do it you should either use [In]
array[], or, ref IntPtr.

Are [In, Out] array[] parameters supported by P/Invoke? or this going to
work on my machine and blowup on someone else's?

Thanks
Jun 27 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

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
7 posts views Thread by heddy | last post: by
4 posts views Thread by Andreas Reiff | last post: by
17 posts views Thread by =?Utf-8?B?U2hhcm9u?= | last post: by
6 posts views Thread by =?Utf-8?B?QWxleGFuZGVyZmU=?= | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.