【问题标题】:Array change in C++ function is not preserved in C#C# 中不保留 C++ 函数中的数组更改
【发布时间】:2012-04-18 00:45:05
【问题描述】:

我有一个调用 C++ 函数的 C# 代码。

C++ 函数应该填充一个用指针传递的缓冲区。但是,数组返回空。

导入声明为:

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 FillArr(char[] arr);

经过简化并输入一些硬编码值后的代码如下所示:

C#代码:

char[] arr= new char[10];
ret = LogicInterface.FillArr(arr);

C++ 代码:

bool FillArr(char* arr)
{
       int length=10;
       for(int i = 0; i < length; i++) 
       {
              arr[i] = 3; //replaced with some hard coded value
       }
       return true;
}

但是,数组仍然是空的。

有什么建议吗?

【问题讨论】:

    标签: c# c++ pointers marshalling dllimport


    【解决方案1】:

    我相信您必须先固定该数组,然后再将其传递给您的本机代码。这可以防止 GC 在您在 C++ 中访问托管数组时在内存中移动它。

    所以你可以使用:

    [DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
    public static extern UInt32 FillArr( char* arr );
    

    然后:

    char[] arr = new char[ 10 ];
    
    fixed (char* pinned = arr )
    {
        ret = LogicInterface.FillArr( pinned );
    }
    

    请注意,我实际上并没有编译和运行它,但它应该会给你一些关于如何继续的想法。

    【讨论】:

      【解决方案2】:

      只要 C++ 中的代码在返回之前不缓存它,就不需要固定数组。

      在您的情况下,您需要通过引用传递数组,以便可以将其视为输出参数。

      [DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
      public static extern UInt32 FillArr(ref char[] arr);`
      

      【讨论】:

      • 然后编组器会将内存固定在引擎盖下吗?
      【解决方案3】:

      发现此链接非常有用:

      C#: calling C++ DLL with char** argument

      最终代码如下:

          [DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
          static extern bool FillArr([MarshalAs(UnmanagedType.LPStr, ArraySubType = UnmanagedType.LPStr)] StringBuilder args);
      
              static void Main(string[] args)
              {
                  StringBuilder arr = new StringBuilder(9);
                  bool res = FillArr(arr);
              }
      

      【讨论】:

      • 啊,你正在编组字符串......不仅仅是原始问题中描述的 char 数组。
      • @Nick 我更喜欢使用 char 数组,但它不起作用。你的答案和另一个也没有。这样我可以将其解析回字符串,并将其用作 char 数组。
      猜你喜欢
      • 2012-12-18
      • 2014-03-10
      • 1970-01-01
      • 2011-08-02
      • 2016-04-22
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      • 1970-01-01
      相关资源
      最近更新 更多