【问题标题】:How to pass parameter that can be of type int/double/string/int[] from C# to native C?如何将类型为 int/double/string/int[] 的参数从 C# 传递到本机 C?
【发布时间】:2016-05-17 08:16:43
【问题描述】:

可以这样做吗:

本机 DLL:

void SetFieldValue(const char *Field, void *pValue, int Count)
{
    char *StrValue;
    int *IntArrayValue;
    if (!strcmp(Field, "StrField"))
    {
        StrValue = malloc((Count + 1) * sizeof(char)); 
        strcpy(StrValue, (char *)pValue);
        DoSomethingWithStringValue(StrValue);
        free(StrValue);
    }
    else if (!strcmp(Field, "IntArrayField"))
    {
        IntArrayValue = malloc(Count * sizeof(int)); 
        memcpy(IntArrayValue, pValue, Count);
        DoSomethingWithIntArrayValue(IntArrayValue);
        free(StrValue);
    }
    //... and so on
}

托管:

[DllImport(DllName, CallingConvention = DllCallingConvention)]
private static extern void SetFieldValue(string fieldName, IntPtr value, int count);


public void SetIntArray()
{
    int[] intArray = { 1, 2, 3 };
    SetFieldValue("IntArrayField", intArray, 3);
}


public void SetString()
{
    SetFieldValue("StrField", "SomeValue", 9);
}

//... and so on

【问题讨论】:

  • 你的问题是什么?你的代码在我看来没问题。
  • 我的问题是 PInvoke 臭名昭著导致难以发现的错误。我正在尝试就如何最好/最安全地完成这类事情征求意见。

标签: c# c pinvoke native managed


【解决方案1】:

一种方法是使用方法重载。在 C# 方面,您将声明导入函数的多个版本。对于问题中的两个示例,如下所示:

[DllImport(DllName, CallingConvention = DllCallingConvention)]
private static extern void SetFieldValue(string fieldName, int[] value, int count);

[DllImport(DllName, CallingConvention = DllCallingConvention)]
private static extern void SetFieldValue(string fieldName, string value, int count);

这两个 p/invoke 函数链接到同一个非托管函数。对于第一个重载,value 参数被编组为指向数组第一个元素的指针。对于第二次重载,value 参数被编组为指向以空字符结尾的字符数组的指针。在这两种情况下,这都是您所需要的。

【讨论】:

  • 谢谢!这是我从未听说过的。所以当这样做时,本机代码就像我的问题一样?这似乎真的是一个很好的方法。
  • 最好包含使用值类型的重载,太容易忘记使用ref
  • @HansPassant:谢谢,但我不明白:“最好包含使用值类型的重载,太容易忘记使用 ref”。我了解您在托管方面的重载,但我问的是我的本机 C 代码。 C-没有重载。
猜你喜欢
  • 2021-09-15
  • 1970-01-01
  • 2019-01-31
  • 2020-11-12
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多