2013-04-10 64 views
1

我输出了一些东西到用c编写的数组,然后我希望从c#调用通过dll获取信息,但是失败了。没有警告,但我可以注意得到正确的信息。测试代码如下:如何从c#通过dll获取c数组?

@ips存储输出信息

UDPDLL_API int get_by_csharp_tst(char *** ips){ 
    char **ip = NULL; 
    int i = 0; 
    *ips = (char**)malloc(sizeof(char*)*10); 
    if(ips == NULL){ 
     perror("overflow"); 
    } 
    ip = *ips; 
    for(i =0 ; i <10 ; i++){ 
     *ip = (char*)malloc(16); 
     memcpy(*ip,"255.255.255.255",16); 
     *ip++; 
    } 
    return 0; 
} 

调用从C#如下:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace dll_call 
{ 
    class Program 
    { 
     [DllImport("udpdll.dll",EntryPoint="get_by_csharp_tst")] 
     public static extern int get_by_csharp_tst(byte [,] ai); 
     static void Main(string[] args) 
     { 
      int i = 0; 
      byte[,] ips = new byte[10, 16]; 
      Program.get_by_csharp_tst(ips); 
      for (i = 0; i < 10; i++) { 
       Console.WriteLine(ips); 
      } 
      Console.Read(); 
     } 
    } 
} 

再次感谢您。任何帮助将不胜感激 !

+0

一个指向指针的指针.. yowza。调试时它会返回什么? – 2013-04-10 10:13:16

+0

'[,]'不是你想象的那样 – leppie 2013-04-10 10:16:55

+1

@SimonWhitehead:这将是'ref string []'(或类似的) – leppie 2013-04-10 10:18:02

回答

0

这是一个可怕的API。

对于初学者来说,从来没有在本地分配内存,如果你不能释放内存的话。

但是,如果你必须,然后阅读。

更改签名public static extern int get_by_csharp_tst(out IntPtr[] ai);

这样称呼它:

IntPtr[] ai; // do not allocate, you are doing it on the native side already 
get_by_csharp_tst(out ai); 
// as we know the size, just use it 
string[] results = new string[10]; 
for (int i = 0; i < 10; i++) 
{ 
    results[i] = Marshal.PtrToStringAnsi(ai[i], 16); 
} 
// you need to free the memory you allocated natively here, else memory leak. 

foreach (var s in results) 
{ 
    Console.WriteLine(s); 
} 

注:指定长度(16)时,你从来没有明确分配的内存将连聚餐并有不保证最后的元素将是\0