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

C# c++ 传递函数指针的更多相关文章

  1. C++传递函数指针

    函数指针是一个很好的类型.因此,您可以编写一个函数,它的一个参数是一个函数指针.然后.在(外部)当函数使用的函数指针参数,来间接调用时调用相应的参数的函数的函数. 因为指针在不同的情况下能够指向不同的 ...

  2. delphi 中的函数指针 回调函数(传递函数指针,以及它需要的函数参数)

    以下代码仅仅是测试代码:delphi XE7 UP1 interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.V ...

  3. 《笨办法学C》笔记之指针

    C语言编程主要操作的对象就是指针. 指针从哪里来 指针就是表示内存存储区域的一组数值,使用%p格式化字符串. Linux系统会为程序维护两个临时变量存储位置:栈.堆.栈的空间少,栈通常在用户更高的地址 ...

  4. 深入理解C指针之三:指针和函数

    原文:深入理解C指针之三:指针和函数 理解函数和指针的结合使用,需要理解程序栈.大部分现代的块结构语言,比如C,都用到了程序栈来支持函数的运行.调用函数时,会创建函数的栈帧并将其推到程序栈上.函数返回 ...

  5. C语言函数指针的使用

    使用函数指针时一定要注意,因为c不会检查参数是否正确 区分返回指针的函数和函数指针 int *f4();返回一个整数指针 int (*f5)();返回整数的函数指针 int * (*f6)();返回整 ...

  6. 《深入理解C指针》

    <深入理解C指针> 基本信息 原书名:Understanding and using C pointers 作者: (美)Richard Reese 译者: 陈晓亮 丛书名: 图灵程序设计 ...

  7. 深入理解C指针----学习笔记

      深入理解C指针     第1章 认识指针   理解指针的关键在于理解C程序如何管理内存,指针包含的就是内存地址.     1.1 指针和内存   C程序在编译后,以三种方式使用内存: 1. 静态. ...

  8. C指针的这些使用技巧,掌握后立刻提升一个Level

    这是道哥的第016篇原创 关注+星标公众号,不错过最新文章 目录 一.前言 二.八个示例 1. 开胃菜:修改主调函数中的数据 2. 在被调用函数中,分配系统资源 2.1 错误用法 2.2 正确用法 3 ...

  9. C#与C/C++的交互zz

    C#与C++交互,总体来说可以有两种方法: 利用C++/CLI作为代理中间层 利用PInvoke实现直接调用 第一种方法:实现起来比较简单直观,并且可以实现C#调用C++所写的类,但是问题是MONO构 ...

随机推荐

  1. CentOS 6.5系统安装配置图解教程(详细图文)

    转载:http://www.jb51.net/os/128751.html

  2. Google浏览器的缓存文件过大(mega网站导致的)

    到选项里清空所有内容也没有用. 后来手动找了一下,原来在这里,存了在这里存了整整10G的缓存: C:\Users\my\AppData\Local\Google\Chrome\User Data\Pr ...

  3. C# RSA在服务上使用出现拒绝方法错误的解决方法

    在做一个快钱接口的时候,遇到了.net RSA加密无法在一台win2008服务器上运行正常,更换到Win2003服务器后出现问题,具体表现如下: “/”应用程序中的服务器错误. ----------- ...

  4. 饭卡------HDOJ杭电2546(还是01背包!!!!!!)

    Problem Description 电子科大本部食堂的饭卡有一种非常诡异的设计,即在购买之前推断剩余金额. 假设购买一个商品之前,卡上的剩余金额大于或等于5元,就一定能够购买成功(即使购买后卡上剩 ...

  5. java.text.NumberFormat使用方法

    NumberFormat 是全部数值格式的抽象基类. 该类提供了格式化和分析数值的接口. NumberFormat 也提供了确定 哪个语言环境具有数值格式以及它们名字的方法. package com. ...

  6. android动效开篇

    大神博客:http://blog.csdn.net/tianjian4592/article/details/44155147 在现在的Android App开发中,动效越来越受到产品和设计师同学的重 ...

  7. iOS NSRuntime机制

    什么是Objective-C runtime? 简单来说,Objective-C runtime是一个实现Objective-C语言的C库.对象可以用C语言中的结构体表示,而方法(methods)可以 ...

  8. BZOJ 1216: [HNOI2003]操作系统( 优先队列 )

    按题意用priority_queue模拟即可 ---------------------------------------------------------------------- #inclu ...

  9. ThinkPHP快捷函数

    16个快捷函数用法 1.A() 实例化控制器  格式:[资源://][模块/]控制器A($name,$layer='',$level='')@param string $name 资源地址   @pa ...

  10. oracle中if/else

    oracle中if/else功能的实现的3种写法   1.标准sql规范 一.单个IF 1. if a=... then ......... end if; 2. if a=... then .... ...