2012-01-05 11 views
5

Tengo una biblioteca nativa con algunos nativos ntype y me gustaría invocar algunas funciones en ella.PInvoke: cómo obtener el 'SomeType * []'?

que fue capaz de reunir para:

foo1(ntype** p) ==> foo1(IntPtr[] p) 

pero no saben cómo hacerlo para:

foo1(ntype*[] p) ==> foo1(<???> p) 

Al menos IntPtr[] no funcionó.

Editar

La función no administrado que estoy tratando de reunir con es:

extern mxArray* mclCreateSimpleFunctionHandle(mxFunctionPtr fcn); 

donde mxFunctionPtr es:

typedef void(*mxFunctionPtr)(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]); 

Esto representa una llamada a la siguiente función de Matlab firma:

function [varargout] = callback(varargins) 
%[ 
    %% Do callback code %% 
%] 

Obviamente, de mis expectativas, este puntero de función debe proporcionarme 2 listas de mxArray*:

  • La lista de argumentos de entrada (es decir, PRHS, inicializado por parte de Matlab)
  • La lista de argumentos de salida (es decir, PLHS, todo inicializado a cero, pero en el que yo debería escribir en)

Actualmente partir de las pruebas que he hecho, sólo se devuelve para primicias mxArray* en plhsprhs y listas

+0

funciones C que toman punteros y las matrices son irremediablemente ambiguas. No hay diferencia entre ntype ** y ntype * [] a menos que de alguna manera le haya dado una semántica diferente en su código. –

Respuesta

1

GOT IT

La maniobra correcta para 'SomeTime* []' en:

extern mxArray* mclCreateSimpleFunctionHandle(mxFunctionPtr fcn); 
typedef void(*mxFunctionPtr)(int nlhs, mxArray* plhs[], int nrhs, mxArray* prhs[]); 

es:

// 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); 

Explicación

MarshalAs atributo indica de formar SomeTime*[] como LPArray de IntPtr, donde el tamaño de la matriz está contenida en el parámetro de función en el índice de base cero SizeParamIndex

2

primero que debe hacer es traducir su nativa ntype en un logrado struct.

Por ejemplo:

public struct Ntype 
{ 
    public int Field1; 
    public long Field2; 
} 

A continuación, defina su método con un simple IntPtr parámetro en el código C#.

[DllImport] 
static void foo1(IntPtr myParam); 

Finalmente aquí es cómo lo usa:

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); 
    } 
} 
+0

¿Por qué no simplemente no define la estructura tanto en su código C# como en C++ y envía la dirección del puntero al código C++? El código sugerido puede provocar problemas. –

+0

Gracias @ ken2k y @Ramhound por su ayuda. Creo que realmente no necesito tener la estructura, solo un indicador de ello está bien para mí. De hecho, estoy tratando de resolver al llamar a 'mclCreateSimpleFunctionHandle' como se describe en [link] (http://stackoverflow.com/q/7892254/684399). Aparentemente, esta función solo está regresando para un puntero al primer 'mxArray *' y estoy tratando de obtener la lista completa de 'mxArray *' (no estoy interesado en 'mxArray' en sí mismo) ... Al menos para lectores en esta otra publicación, supongo que estoy en camino de arreglarlo. – CitizenInsane

Cuestiones relacionadas