By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,887 Members | 1,246 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,887 IT Pros & Developers. It's quick & easy.

passing array of structs to unmanaged code

P: n/a
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
Share this Question
Share on Google+
2 Replies


P: n/a
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

P: n/a
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.