C# C+中的数组更改+;函数不保留在C中#

C# C+中的数组更改+;函数不保留在C中#,c#,c++,pointers,marshalling,dllimport,C#,C++,Pointers,Marshalling,Dllimport,我有一个C++代码,调用C++函数。< /p> C++函数应该填充一个指针传递的缓冲区。但是,数组返回空 进口报关单为: [DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)] public static extern UInt32 FillArr(char[] arr); 经过简化并输入一些硬编码值后,代码如下所示: C#中的代码: <

我有一个C++代码,调用C++函数。< /p>

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

进口报关单为:

[DllImport("ProjectLogicInterface", EntryPoint = "FillArr", CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 FillArr(char[] arr);
经过简化并输入一些硬编码值后,代码如下所示:

C#中的代码:

< > 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;
}
bool FillArr(char*arr)
{
整数长度=10;
for(int i=0;i
但是,数组仍然为空


有什么建议吗?

我认为在将数组传递给本机代码之前,必须先锁定该数组。这防止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 );
}

注意到,我还没有编译和运行这个,但是它应该给你一些关于如何继续的想法。

< P>你不需要针数组,只要C++中的代码在返回之前不缓存它。 在本例中,需要通过引用传递数组,以便将其视为out参数

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

发现此链接非常有用:

最后的代码如下所示:

    [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);
        }

然后编组员会把记忆钉在引擎盖下吗?啊,你在编组字符串。。。不仅仅是原始问题中描述的字符数组。@Nick我更喜欢使用字符数组,但它不起作用。你的答案和另一个答案也一样。通过这种方式,我可以将其解析回字符串,并将其用作字符数组。
    [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);
        }