2012-01-05 18 views
5

我有一個本地庫,其中包含一些原生的ntype,並且想要在其中調用一些函數。PInvoke - 如何編組''SomeType * []'?

我能元帥:

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

但不知道如何做到這一點的:

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

至少IntPtr[]沒有奏效。

編輯

我試圖與當元帥的非託管函數是:

extern mxArray* mclCreateSimpleFunctionHandle(mxFunctionPtr fcn); 

其中mxFunctionPtr是:

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

這代表下面的MATLAB函數的調用簽名:

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

顯然,從我的期望,這個函數指針應爲我提供了2所列出的mxArray*

  • 的輸入參數列表(即prhs,初始化在MATLAB的一側)
  • 的輸出參數列表(即plhs,全部初始化爲0,但我應該寫成)
從我所做的測試

目前,它只返回首創mxArray*plhsprhs名單

+0

C函數和數組是無望的含糊不清。 ntype **和ntype * []之間沒有區別,除非您在代碼中以某種方式賦予其不同的語義。 – 2012-01-05 14:33:06

回答

1

得到它

爲 'SomeTime* []' 正確編組:

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

是:

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

說明

MarshalAs屬性指示編組SomeTime*[]作爲IntPtr,其中該陣列的尺寸是由函數的參數的基於零的索引在含有LPArray稱取指針SizeParamIndex

2

首先要做的事情是你的本地ntype轉化爲管理struct

例如:

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

然後你在你的C#代碼的簡單IntPtr參數定義你的方法。

[DllImport] 
static void foo1(IntPtr myParam); 

最後這裏是你如何使用它:

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

爲什麼他不在C#和C++代碼中定義結構,並將指針的地址發送給C++代碼,您提出的代碼會讓人們陷入困境。 – 2012-01-05 16:23:55

+0

感謝@ ken2k和@Ramhound的幫助。我想我並不需要這個結構,只有一個指向它的指針對我來說很好。事實上,我試圖按照[鏈接](http://stackoverflow.com/q/7892254/684399)中所述調用'mclCreateSimpleFunctionHandle'。顯然,這個函數只是返回一個指向第一個'mxArray *'的指針,我試圖獲得'mxArray *'的完整列表(我對mxArray本身不感興趣)......至少在其他帖子上的讀者,猜測我正在修復它。 – CitizenInsane 2012-01-05 18:09:03