zoukankan      html  css  js  c++  java
  • 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<<"
    array length:"<<size<<"
    ";
    	std::cout << "entry fnsort in cpp
    ";
    	for(int index=0; index<size;index++){
    		std::cout << arr[index] << " ";
    	}
    	qsort(arr,size,sizeof(int),fuccsharp);
    	std::cout<<"
     sort end
    ";
    	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("
    end");
                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

  • 相关阅读:
    使用CORS解决flask前端页面跨域问题
    re.search 与 re.match的区别
    jupyter-notebook快捷键的使用
    docker端口的映射顺序
    [转]/dev/null 命令用法
    [转]Docker容器内不能联网的6种解决方案
    牛客网python试题-错误整理-20180711
    docker常用命令
    linux实用命令-待补充
    docker exec小脚本
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3317911.html
Copyright © 2011-2022 走看看