How to get a Pointer to a managed Array to pass to DLL Function?

G

Guest

Thanks to BMermuys I can now copy data from an unmanage
Array to a Managed Array as I do in dbl_read

My -maybe stupid- question

How does it work the other way around

You can see what I tried in dbl_write

How to do the Marshal Copy to my Pointe
or how to get a Pointer to my data[] Array

I tried Marshal.StructureToPtr, &, and Marshal.Copy bu
none worked

Thanks in Advanc

Marti

using System
using System.Runtime.InteropServices

namespace Dickenbestimmun

/// <summary
/// Summary description for FileIO
/// </summary


public class FileI


public int maxindex
public int canFloat
public int[] resolution
public float[] length
public double[][][] VoxelData
double[] data
IntPtr pData = IntPtr.Zero

[DllImport("OMASLIB.DLL", SetLastError=true)
public static extern int omas_dbl_write
[MarshalAs(UnmanagedType.LPStr)] string fname
[In, Out] int[] res
[In, Out] float[] len
ref IntPtr data
int canFloat)

public int dbl_write(string fname

//Marshal.Copy ( data, pData, 0, maxindex )

int result = omas_dbl_write( fname, resolution, length, ref pData, canFloat )

return result


[DllImport("OMASLIB.DLL", SetLastError=true)
public static extern int omas_dbl_read
[MarshalAs(UnmanagedType.LPStr)] string fname
[In, Out] int[] res
[In, Out] float[] len
ref IntPtr data)

public int dbl_read(string fname

int result = 0
resolution = new int[] {0,0,0,0}
length = new float[] {0,0,0,0 }

canFloat = omas_dbl_read( fname, resolution, length, ref pData )
maxindex = resolution[0]* resolution[1] * resolution[2]* resolution[3]; // calculate _number of elements_ in dat
data = new double[maxindex]
Marshal.Copy ( pData, data, 0, maxindex )

return canFloat


public FileIO(

/
// TODO: Add constructor logic her
/
 
B

BMermuys

Hi,
[inline]

Chucker said:
Thanks to BMermuys I can now copy data from an unmanaged
Array to a Managed Array as I do in dbl_read.

My -maybe stupid- question:

How does it work the other way around?

You can see what I tried in dbl_write.

How to do the Marshal Copy to my Pointer
or how to get a Pointer to my data[] Array?

I tried Marshal.StructureToPtr, &, and Marshal.Copy but
none worked.

For the reading part:
You didn't know the size of the array before calling the function so you
could not allocate any managed memory for it. That's why unmanaged memory
is used and a copy from unmanaged to managed heap must be done. And the
reason you need to do the copy yourself is because the framework doesn't
know the size of the returned array...

For the writing part:
You forgot to write how the C function, if data is an one-dimensional array
(e.g. double* ), then you must know a way to translate between 4D and 1D.
Then you could only store an one-dimensional array and have some 4D methods
to manipulate the 1D data. This way you can easily pass the 1D array
without any copy.

If you write the data then I assume the array is fixed in size and size is
not changed by the function. If so, the framework can pin it and no copy
must be done, the dll function can use the managed data because it's pinned.
The framework will do this pinning for you.


public int maxindex;
public int canFloat;
public int[] resolution;
public float[] length;
public double[][][] VoxelData;
// wasn't this 4D ?
// are you sure about a jagged array
// multi-dimension arrays are declared as double[,,,] data = new
double[10,10,10,10];
// OR make methods that take md-cordinates to manipulate and read the 1d
data
double[] data;
IntPtr pData = IntPtr.Zero;

[DllImport("OMASLIB.DLL", SetLastError=true)]
public static extern int omas_dbl_write(
[MarshalAs(UnmanagedType.LPStr)] string fname,
[In, Out] int[] res,
[In, Out] float[] len,
[In, Out] double[] data,
int canFloat);

public int dbl_write(string fname)
{
int result = omas_dbl_write( fname, resolution, length, data,
canFloat );
return result;
}

HTH,
Greetings
Thanks in Advance

Martin

using System;
using System.Runtime.InteropServices;

namespace Dickenbestimmung
{
/// <summary>
/// Summary description for FileIO.
/// </summary>


public class FileIO
{

public int maxindex;
public int canFloat;
public int[] resolution;
public float[] length;
public double[][][] VoxelData;
double[] data;
IntPtr pData = IntPtr.Zero;

[DllImport("OMASLIB.DLL", SetLastError=true)]
public static extern int omas_dbl_write(
[MarshalAs(UnmanagedType.LPStr)] string fname,
[In, Out] int[] res,
[In, Out] float[] len,
ref IntPtr data,
int canFloat);

public int dbl_write(string fname)
{
//Marshal.Copy ( data, pData, 0, maxindex );

int result = omas_dbl_write( fname, resolution, length, ref pData, canFloat );

return result;
}

[DllImport("OMASLIB.DLL", SetLastError=true)]
public static extern int omas_dbl_read(
[MarshalAs(UnmanagedType.LPStr)] string fname,
[In, Out] int[] res,
[In, Out] float[] len,
ref IntPtr data);

public int dbl_read(string fname)
{
int result = 0;
resolution = new int[] {0,0,0,0};
length = new float[] {0,0,0,0 };

canFloat = omas_dbl_read( fname, resolution, length, ref pData );
maxindex = resolution[0]* resolution[1] * resolution[2]* resolution[3];
// calculate _number of elements_ in data
data = new double[maxindex];
Marshal.Copy ( pData, data, 0, maxindex );

return canFloat;
}

public FileIO()
{
//
// TODO: Add constructor logic here
//
}
}
}
 
B

BMermuys

Chucker said:
Thanks again!
You're welcome.
That was easy :blush:) And it works. The Conversion 4D->1D is no
problem here. I moved that to a New Class "DataStack".

That's a good idea.

Greetings

using System;
using System.Xml;
using System.Runtime.InteropServices;

namespace Dickenbestimmung
{
/// <summary>
/// Summary description for FileIO.
/// </summary>


public class FileIO:IDisposable
{
public int maxindex;
public int canFloat;
public double[] data;
private IntPtr pData = IntPtr.Zero;
private bool disposed = false;

[DllImport("OMASLIB.DLL", SetLastError=true)]
public static extern int omas_dbl_write(
[MarshalAs(UnmanagedType.LPStr)] string fname,
[In, Out] int[] res,
[In, Out] float[] len,
[In, Out] double[] data,
int canFloat);

public int dbl_write(string fname,ref int[] resolution, ref float[] length,int canFloat)
{
if(this.disposed)
{
throw new ObjectDisposedException("This means Trouble");
}

int result = omas_dbl_write( fname, resolution, length, data, canFloat );

return result;
}

[DllImport("OMASLIB.DLL", SetLastError=true)]
public static extern int omas_dbl_read(
[MarshalAs(UnmanagedType.LPStr)] string fname,
[In, Out] int[] res,
[In, Out] float[] len,
ref IntPtr data);

public int dbl_read(string fname, ref int[] resolution, ref float[] length )
{
canFloat = omas_dbl_read( fname, resolution, length, ref pData );
maxindex = resolution[0]* resolution[1] * resolution[2]* resolution[3];
// calculate _number of elements_ in data
data = new double[maxindex];
Marshal.Copy ( pData, data, 0, maxindex );

return canFloat;
}

protected virtual void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
data = null;
maxindex = 0;
canFloat = 0;
}
pData = IntPtr.Zero;
}
disposed = true;
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

~FileIO()
{
Dispose(false);
}

public FileIO()
{
}
}
}
 

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