如何通过dll从c#获取c数组?

时间:2022-12-22 01:39:12

I output something to a array written in c , then I hope to get the information from c# calling via dll, but failed. No warnnings but I can note get the informaton correctly. Test code as follow :

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

@ips store the output information

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

calling from c# as follow :

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

Thank you again. Any help would be greatly appreciated !

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

1 个解决方案

#1


0  

This is a horrible API.

这是一个可怕的API。

For starters, never allocate memory on the native side, if you cannot free it there too.

对于初学者来说,永远不要在本机上分配内存,如果你也不能在那里释放它。

But if you have to, then read on.

但如果必须,请继续阅读。

Change the signature to public static extern int get_by_csharp_tst(out IntPtr[] ai);

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

Call it like:

称之为:

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

Note: It will be potluck even when specifying the length (16) as you never clear the allocated memory and there is no guarantee the last element will be \0.

注意:即使在指定长度(16)时它也将是potluck,因为你从不清除分配的内存,并且不能保证最后一个元素是\ 0。

#1


0  

This is a horrible API.

这是一个可怕的API。

For starters, never allocate memory on the native side, if you cannot free it there too.

对于初学者来说,永远不要在本机上分配内存,如果你也不能在那里释放它。

But if you have to, then read on.

但如果必须,请继续阅读。

Change the signature to public static extern int get_by_csharp_tst(out IntPtr[] ai);

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

Call it like:

称之为:

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

Note: It will be potluck even when specifying the length (16) as you never clear the allocated memory and there is no guarantee the last element will be \0.

注意:即使在指定长度(16)时它也将是potluck,因为你从不清除分配的内存,并且不能保证最后一个元素是\ 0。