【问题标题】:Marshalling native .dll in C# with multiple pointers在 C# 中使用多个指针编组本机 .dll
【发布时间】:2016-09-28 06:45:06
【问题描述】:

在 C++ 中有以下代码:

  • nConId 是连接标识符
  • pParName 参数名称
  • pSubName 子参数名称(如果有)
  • pValue_out 指向长度为 FCL_PAR_VALUE_LENGH 的 char 数组的指针
  • 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,所以我猜我的调用有问题。

我的 marshall 错了吗?为了获得良好的响应,我必须对代码进行哪些更改?

PS:我也知道调用也会返回一些东西给aParValue

【问题讨论】:

    标签: c# pinvoke marshalling mixed-mode


    【解决方案1】:

    你对那些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

    【讨论】:

    • 工作就像一个魅力!非常感谢:)
    猜你喜欢
    • 2010-10-18
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多