I have a native library with some native ntype
in it and would like to p/invoke some functions in it.
I was able to marshal for:
foo1(ntype** p) ==> foo1(IntPtr[] p)
But don't know how to do it for:
foo1(ntype*[] p) ==> foo1(<???> p)
At least IntPtr[]
did not worked.
Edit
The unmanaged function I'm trying to marshal with is:
extern mxArray* mclCreateSimpleFunctionHandle(mxFunctionPtr fcn);
where mxFunctionPtr
is:
typedef void(*mxFunctionPtr)(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);
This represent a call to the following matlab function signature:
function [varargout] = callback(varargins)
%[
%% Do callback code %%
%]
Obviously, from my expectations, this function pointer should provide me with 2 lists of mxArray*
:
Currently from the tests I've made, it only returns for firsts mxArray*
in plhs
and prhs
lists
First thing to do is to translate your native ntype
into a managed struct
.
For instance:
public struct Ntype
{
public int Field1;
public long Field2;
}
Then you define your method with a simple IntPtr
parameter in your C# code.
[DllImport]
static void foo1(IntPtr myParam);
Finally here's how you use it:
IntPtr buffer = IntPtr.Zero;
try
{
// Allocates a buffer. The size must be known
buffer = Marshal.AllocHGlobal(0x1000);
// Call to your unmanaged method that fills the buffer
foo1(buffer);
// Casting the unmanaged memory to managed structure that represents
// your data
Ntype obj = (Ntype)Marshal.PtrToStructure(buffer, typeof(Ntype));
}
finally
{
// Free unmanaged memory
if (buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(buffer);
}
}
Got it
The correct marshalling for 'SomeTime* []
' in:
extern mxArray* mclCreateSimpleFunctionHandle(mxFunctionPtr fcn);
typedef void(*mxFunctionPtr)(int nlhs, mxArray* plhs[], int nrhs, mxArray* prhs[]);
is:
// For function pointer
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate void MCRInteropDelegate(int nlhs,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.SysInt, SizeParamIndex = 0)][Out] IntPtr[] plhs,
int nrhs,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.SysInt, SizeParamIndex = 2)][In] IntPtr[] prhs);
// For API function
[DllImport(DLLNAME, EntryPoint = "mclCreateSimpleFunctionHandle", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
private static extern IntPtr _mclCreateSimpleFunctionHandle(MCRInteropDelegate fctn);
Explanation
MarshalAs
attribute indicates to marshal SomeTime*[]
as a LPArray
of IntPtr
, where the size of the array is contained by function's parameter at the zero-based index SizeParamIndex
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With