Newbie: API function call with array pointer as argument

Z

zhilko

Hi,
I'm from C/C++ world and now having troubles converting my old C++
code to C#

The OpenGL function is declared as
void glMultMatrixd( const GLdouble *m );
In C++, I use the code

//-------------------class definition
class CMatrix
{
public: double xx, yx, zx, x0;
double xy, yy, zy, y0;
double xz, yz, zz, z0;
double px, py, pz, w1;
.....
}

//--------------------using
CMatrix myMatrix
glMultMatrixd(&myMatrix.xx)

For C# I'm using the OpenGL wrapper from
http://nehe.gamedev.net/counter.asp?file=files/basecode/nehegl_csharp.zip

I'm trying to use it in such way:
//------------------------definition
namespace MyFormProject
{
public class Matrix
{
public double xx, yx, zx, x0,
xy, yy, zy, y0,
xz, yz, zz, z0,
px, py, pz, w1;
.....
}
}

// -----------------------------wrapper imports OpenGL functions
[DllImport(GL_DLL,EntryPoint ="glMultMatrixd")]
public static extern void glMultMatrixd(double[] m);

// ----------------------using
private unsafe void Draw(Matrix m)
{
fixed (double* d = &m.xx)
{
GL.glMultMatrixd (d); // compiler error!
}
}

This causes the compiler error "Cannot convert double * to double []".
How to do it correctly?

Thanx in advance
Roman.
 
N

Nicholas Paldino [.NET/C# MVP]

You will have to declare the Open GL function as unsafe to allow the use
of pointers:

[DllImport(GL_DLL,EntryPoint ="glMultMatrixd")]
public static unsafe extern void glMultMatrixd(double* m);

You might want to be careful, if the function is expecting yx to come
after xx in memory, zx after yx, etc, etc, then you aren't going to be able
to get this to work, as it is not guaranteed that those members will be
stored in that order in memory.

You will have to copy the values to an array (so that you can guarantee
that it is contiguous) and then pass that.

Either that, or store them in an array in your class to begin with.
 
B

Ben Voigt [C++ MVP]

Nicholas Paldino said:
You will have to declare the Open GL function as unsafe to allow the
use of pointers:

[DllImport(GL_DLL,EntryPoint ="glMultMatrixd")]
public static unsafe extern void glMultMatrixd(double* m);

You might want to be careful, if the function is expecting yx to come
after xx in memory, zx after yx, etc, etc, then you aren't going to be
able to get this to work, as it is not guaranteed that those members will
be stored in that order in memory.

With .NET, you can, using the FieldOffset function. Far better though, to
use an actual array, and define properties as convenience accessors.

The C++ code was totally broken.
You will have to copy the values to an array (so that you can guarantee
that it is contiguous) and then pass that.

Either that, or store them in an array in your class to begin with.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Hi,
I'm from C/C++ world and now having troubles converting my old C++
code to C#

The OpenGL function is declared as
void glMultMatrixd( const GLdouble *m );
In C++, I use the code

//-------------------class definition
class CMatrix
{
public: double xx, yx, zx, x0;
double xy, yy, zy, y0;
double xz, yz, zz, z0;
double px, py, pz, w1;
....
}

//--------------------using
CMatrix myMatrix
glMultMatrixd(&myMatrix.xx)

For C# I'm using the OpenGL wrapper from
http://nehe.gamedev.net/counter.asp?file=files/basecode/nehegl_csharp.zip

I'm trying to use it in such way:
//------------------------definition
namespace MyFormProject
{
public class Matrix
{
public double xx, yx, zx, x0,
xy, yy, zy, y0,
xz, yz, zz, z0,
px, py, pz, w1;
....
}
}

// -----------------------------wrapper imports OpenGL functions
[DllImport(GL_DLL,EntryPoint ="glMultMatrixd")]
public static extern void glMultMatrixd(double[] m);

// ----------------------using
private unsafe void Draw(Matrix m)
{
fixed (double* d = &m.xx)
{
GL.glMultMatrixd (d); // compiler error!
}
}

This causes the compiler error "Cannot convert double * to double []".
How to do it correctly?

Thanx in advance
Roman.
 
N

Nicholas Paldino [.NET/C# MVP]

Ben,

Yes, or use the StructLayout attribute (which would be needed with the
FieldOffset attribute as well), initialized to to LayoutKind.Sequential.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
Nicholas Paldino said:
You will have to declare the Open GL function as unsafe to allow the
use of pointers:

[DllImport(GL_DLL,EntryPoint ="glMultMatrixd")]
public static unsafe extern void glMultMatrixd(double* m);

You might want to be careful, if the function is expecting yx to come
after xx in memory, zx after yx, etc, etc, then you aren't going to be
able to get this to work, as it is not guaranteed that those members will
be stored in that order in memory.

With .NET, you can, using the FieldOffset function. Far better though, to
use an actual array, and define properties as convenience accessors.

The C++ code was totally broken.
You will have to copy the values to an array (so that you can
guarantee that it is contiguous) and then pass that.

Either that, or store them in an array in your class to begin with.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Hi,
I'm from C/C++ world and now having troubles converting my old C++
code to C#

The OpenGL function is declared as
void glMultMatrixd( const GLdouble *m );
In C++, I use the code

//-------------------class definition
class CMatrix
{
public: double xx, yx, zx, x0;
double xy, yy, zy, y0;
double xz, yz, zz, z0;
double px, py, pz, w1;
....
}

//--------------------using
CMatrix myMatrix
glMultMatrixd(&myMatrix.xx)

For C# I'm using the OpenGL wrapper from
http://nehe.gamedev.net/counter.asp?file=files/basecode/nehegl_csharp.zip

I'm trying to use it in such way:
//------------------------definition
namespace MyFormProject
{
public class Matrix
{
public double xx, yx, zx, x0,
xy, yy, zy, y0,
xz, yz, zz, z0,
px, py, pz, w1;
....
}
}

// -----------------------------wrapper imports OpenGL functions
[DllImport(GL_DLL,EntryPoint ="glMultMatrixd")]
public static extern void glMultMatrixd(double[] m);

// ----------------------using
private unsafe void Draw(Matrix m)
{
fixed (double* d = &m.xx)
{
GL.glMultMatrixd (d); // compiler error!
}
}

This causes the compiler error "Cannot convert double * to double []".
How to do it correctly?

Thanx in advance
Roman.
 
Top