C# 调用DLL多级指针和多维数组问题。

1、数组和循环指针

C语言接口:结构体中含本身的指针myApi_sIp *pNext; 

#pragma once

#ifndef _DLL_API
#ifdef DLL_EXPORTS  
#define _DLL_API _declspec(dllexport)  
#else  
#define _DLL_API _declspec(dllimport)  
#endif  
#endif // !_DLL_API


struct myApi_sIp
{
	char szIp[40];
	myApi_sIp *pNext;
};

typedef void(_stdcall * myApi_Call) (myApi_sIp *p,int nNum);

extern "C" _DLL_API  int _stdcall MyApi_Test(int *a, myApi_sIp **b);
extern "C" _DLL_API  void _stdcall MyApi_EndTest(myApi_sIp *b);
extern "C" _DLL_API void _stdcall MyApi_CallBack(myApi_Call pFun);

C#使用

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


[StructLayout(LayoutKind.Sequential)]
public struct myApi_sIp
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
    public string szIp;
    public IntPtr pNext;
}

namespace ConsoleApp1
{
    class Program
    {
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate void myApi_Call(IntPtr p, int num2);

        [DllImport("ConsoleApplication3.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int MyApi_Test(ref int a, out IntPtr b);

        [DllImport("ConsoleApplication3.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern void MyApi_EndTest(IntPtr b);

        [DllImport("ConsoleApplication3.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern void MyApi_CallBack(myApi_Call b);

        static void Main(string[] args)
        {
            //指针
            {
                IntPtr v;

                int nNum = 0;

                MyApi_Test(ref nNum, out v);

                myApi_sIp r;
                for (int i = 0; i < nNum; i++)
                {
                    IntPtr ptr = new IntPtr(v.ToInt32() + Marshal.SizeOf(typeof(myApi_sIp)) * i);
                    r = (myApi_sIp)Marshal.PtrToStructure(ptr, typeof(myApi_sIp));
                    Console.WriteLine(ptr.ToString());
                }

                IntPtr pNext = v;
                while (IntPtr.Zero != pNext)
                {
                    r = (myApi_sIp)Marshal.PtrToStructure(pNext, typeof(myApi_sIp));
                    pNext = r.pNext;
                    Console.WriteLine(pNext.ToString());
                }

                MyApi_EndTest(v);
            }

            {
                //回调
             MyApi_CallBack((IntPtr p, int num2) =>
                {
                    myApi_sIp r;
                    IntPtr pNext = p;
                    while (IntPtr.Zero != pNext)
                    {
                        r = (myApi_sIp)Marshal.PtrToStructure(pNext, typeof(myApi_sIp));
                        pNext = r.pNext;
                        Console.WriteLine(pNext.ToString());
                    }
                });
            }
            GC.Collect();
            Console.ReadKey();
          



        }
    }
}

2、结构体含多级指针

C语言结构体

struct TYSearch_SeverInfo {
	char szIp[20][80];        //ip地址
};

C#取巧做法:

    [StructLayout(LayoutKind.Sequential)]
    public struct TYSearch_SeverInfoIpString
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
        public string strIp;
    };

    [StructLayout(LayoutKind.Sequential)]
    public struct TYSearch_SeverInfo
    {  
        [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 20)]
        public TYSearch_SeverInfoIpString[] szIp; //ip地址      
    };

C#正常做法:需要使用Marshal进行转换。

    [StructLayout(LayoutKind.Sequential)]
    public struct TYSearch_SeverInfo
    {
        [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 20 * 80)]
        public byte[] szIp; //ip地址   
    };



你可能感兴趣的:(C# 调用DLL多级指针和多维数组问题。)