C# c++ 传递函数指针

C#和c++之间相互传递函数指针

 

在C++和C#之中都有很多callback method,可以相互调用吗,怎么传递,是我表弟的问题.

1.定义c++ dll ,导出方法

 

// sort.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"

#include "sort.h"

#include "stdlib.h"

#include "iostream"

// 这是导出函数的一个示例。

typedef  int (__cdecl *compare )(const void *elem1, const void *elem2 ) ;

void fnsort(int arr[],int size,compare fuccsharp)

{

	std::cout<<"\r\narray length:"<<size<<"\r\n";

	std::cout << "entry fnsort in cpp\r\n";

	for(int index=0; index<size;index++){

		std::cout << arr[index] << " ";

	}

	qsort(arr,size,sizeof(int),fuccsharp);

	std::cout<<"\r\n sort end\r\n";

	for(int index=0; index<size;index++){

		std::cout << arr[index] << " ";

	}

	return ;

}


定义导出文件sort.def

LIBRARY   BTREE

EXPORTS
   fnsort

现在我们期待c#能呼叫fnsort,并实现funccsharp来实现排序算法,在c#中LoadLibrary,GetProcAddress,FreeLibrary当然是必不可少的.另外定义接口实现compare ,传入两个const void *,传出int

 

static int SortASC(IntPtr a, IntPtr b) {

    int va = System.Runtime.InteropServices.Marshal.ReadInt32(a);

    int vb = System.Runtime.InteropServices.Marshal.ReadInt32(b);

    return va - vb;

}

static int SortDESC(IntPtr a, IntPtr b)

{

    int va = System.Runtime.InteropServices.Marshal.ReadInt32(a);

    int vb = System.Runtime.InteropServices.Marshal.ReadInt32(b);

    return vb - va;

}

同时定义委托

 

[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]

public delegate int INTARRAYSORT(IntPtr a, IntPtr b);

 

 

现在我们认为我们实现了int (__cdecl *compare )(const void *elem1, const void *elem2 ) ;现在没事了,一切顺利了,Marshal.GetDelegateForFunctionPointer会将一个intptr转换为一个委托 ,new delegate(pfunc)可以将一个csharp func转换为一个函数指针传绘cpp,依上例,完整实现

 

using System;

using System.Text;

using System.Runtime.InteropServices;





namespace callDLL

{

    class Program

    {

        [DllImport("kernel32")]

        public static extern IntPtr LoadLibrary(string lpFileName);

        [DllImport("Kernel32")]

        public static extern bool FreeLibrary(IntPtr handle);

        [DllImport("Kernel32")]

        public static extern IntPtr GetProcAddress(IntPtr handle, String funcname);





        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]

        public delegate int INTARRAYSORT(IntPtr a, IntPtr b);

        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]

        public delegate void CPPSORT(int[] arr, int size, INTARRAYSORT callback);









        static int SortASC(IntPtr a, IntPtr b) {

            int va = System.Runtime.InteropServices.Marshal.ReadInt32(a);

            int vb = System.Runtime.InteropServices.Marshal.ReadInt32(b);

            return va - vb;

        }

        static int SortDESC(IntPtr a, IntPtr b)

        {

            int va = System.Runtime.InteropServices.Marshal.ReadInt32(a);

            int vb = System.Runtime.InteropServices.Marshal.ReadInt32(b);

            return vb - va;

        }

        static void Main(string[] args)

        {

            IntPtr dll = LoadLibrary("sort.dll");

            IntPtr func=GetProcAddress(dll, "fnsort");

            CPPSORT cppsort = (CPPSORT)Marshal.GetDelegateForFunctionPointer(func, typeof(CPPSORT));

            int[] arr = new int[] { 1, 7, 4 };

            //回叫函数可以使用委托实现

            cppsort(arr,arr.Length,new INTARRAYSORT(SortASC));

            cppsort(arr, arr.Length, new INTARRAYSORT(SortDESC));

            FreeLibrary(dll);

            Console.WriteLine("\r\nend");

            Console.Read();

        }

    }

}

 



输出如下

 

 
  



array length:3
entry fnsort in cpp
1 7 4
 sort end
1 4 7
array length:3
entry fnsort in cpp
1 4 7
 sort end
7 4 1
end

 

 

你可能感兴趣的:(函数指针)