当前位置:编程学习 > C/C++ >>

C# c++ 传递函数指针

C#和c++之间相互传递函数指针
 
在C++和C#之中都有很多callback method,可以相互调用吗,怎么传递,是我表弟的问题.
 
1.定义c++ dll ,导出方法
 
// sort.cpp : 定义 DLL 应用程序的导出函数。
//
 
[cpp]  
#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
 
[csharp]  
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;  
}  
同时定义委托
[csharp] 
[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,依上例,完整实现
 
[csharp]  
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();  
        }  
    }  
}  
 
 
输出如下
[plain]  
  
 
 
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
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,