2016-05-30 34 views
2

具有C++以下代碼:編組在C#天然的.dll與多個指針

  • nConId是連接標識符
  • pParName參數名
  • pSubName子參數名稱(如果有的話)
  • pValue_out指向長度爲char數組的指針FCL_PAR_VALUE_LENGH
  • nValueSize pValue_out向量的實際大小(至少爲FCL_PAR_VALUE_LENGH)
extern "C" MY_API int ReadParameter(const ConnectionId_T nConId, const char* pParName, 
    const char *pSubName, char *pValue_out, const int nValueSize); 

我的嘗試是:

[DllImport("mydll.dll", CharSet = CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)] 
public static extern int ReadParameter(ConnectionId_T pConId, IntPtr pParName, 
    ref IntPtr pSubName, ref IntPtr[] pValue_out, int nValueSize); 

我用下面的代碼來調用該函數:

# nConId is returned from another function and the his value is 0 

public const int FCL_PAR_VALUE_LENGH = 128; 

string param_string = "AUXF"; 
IntPtr pParName = (IntPtr)Marshal.StringToHGlobalAnsi(param_string); 

string subparam_string = "T"; 
IntPtr pSubName = (IntPtr)Marshal.StringToHGlobalAnsi(subparam_string); 

IntPtr[] aParValue = new IntPtr[FCL_PAR_VALUE_LENGH]; 

int returnedValue = ReadParameter(nConId, pParName, ref pSubName, 
    ref aParValue, FCL_PAR_VALUE_LENGH); 

當我運行代碼,我得到一個AccessViolationException,所以我想我的電話有問題。

我的馬歇爾錯了嗎?爲了獲得良好的響應,我需要在代碼中更改哪些內容?

PS:我也知道該電話還返回aParValue

回答

3

你正在努力與那些char* s。這是完全合法的(並鼓勵)編組輸入System.String,輸出StringBuilder

[DllImport("mydll.dll", CharSet = CharSet.Ansi,CallingConvention=CallingConvention.Cdecl)] 
public static extern int ReadParameter(
    ConnectionId_T pConId, 
    string pParName, 
    string pSubName, 
    StringBuilder pValue_out, 
    int nValueSize); 

使用

const int sbLength = 256; //use a domain relevant value 
StringBuilder sb = new StringBuilder(sbLength + 1); //for null character, hard to say if you need it without seeing the C++ code, but easier to just add it than find out. 
int result = ReadParameter(conId, "paramname", "paramsubname", sb, sbLength); 

您還沒有給出有關基本型ConnectionId_T所以我假設你已經排除了這種可能性作爲一個問題的任何跡象。

MSDN Reference

+0

工作就像一個魅力!非常感謝 :) –