2012-04-04 62 views
2

我有一个调用C++函数的C#代码。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; 
} 

但是,该阵列仍为空。

有什么建议吗?

回答

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

请注意,我并没有实际编译和运行这一点,但它应该给你如何进行的一些想法。

1

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

在你的情况,你需要通过引用传递数组,所以它可以被视为一个out参数。

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

会编组,然后针罩下的内存? – Nick 2012-04-04 10:25:34

+0

是的。看到这里:http://msdn.microsoft.com/en-us/magazine/cc163910.aspx#S2 – Pedro 2012-04-04 10:59:49

-1

发现这个链接有用的高度:

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); 
     } 
+0

啊,你是编组字符串......不只是在原始问题中描述的字符数组。 – Nick 2012-04-04 12:07:14

+0

@Nick我宁愿使用char数组,但它不起作用。你的答案和另一个答案也没有。这样我可以将它解析回字符串,并将其用作字符数组。 – sara 2012-04-04 12:18:59