使用多个指针在 C# 中编组本机 .dll

Marshalling native .dll in C# with multiple pointers

在 C++ 中有以下代码:

  • nConId is Connection Identifier
  • pParName the parameter name
  • pSubName the subParameter Name (if any)
  • pValue_out a pointer to a char array of lenght FCL_PAR_VALUE_LENGH
  • nValueSize the real size of pValue_out vector (at least 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: 我也知道调用returns也有事要aParValue.

你为那些 char* 工作太辛苦了。编组输入 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