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
C# c++ 传递函数指针的更多相关文章
- C++传递函数指针
函数指针是一个很好的类型.因此,您可以编写一个函数,它的一个参数是一个函数指针.然后.在(外部)当函数使用的函数指针参数,来间接调用时调用相应的参数的函数的函数. 因为指针在不同的情况下能够指向不同的 ...
- delphi 中的函数指针 回调函数(传递函数指针,以及它需要的函数参数)
以下代码仅仅是测试代码:delphi XE7 UP1 interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.V ...
- 《笨办法学C》笔记之指针
C语言编程主要操作的对象就是指针. 指针从哪里来 指针就是表示内存存储区域的一组数值,使用%p格式化字符串. Linux系统会为程序维护两个临时变量存储位置:栈.堆.栈的空间少,栈通常在用户更高的地址 ...
- 深入理解C指针之三:指针和函数
原文:深入理解C指针之三:指针和函数 理解函数和指针的结合使用,需要理解程序栈.大部分现代的块结构语言,比如C,都用到了程序栈来支持函数的运行.调用函数时,会创建函数的栈帧并将其推到程序栈上.函数返回 ...
- C语言函数指针的使用
使用函数指针时一定要注意,因为c不会检查参数是否正确 区分返回指针的函数和函数指针 int *f4();返回一个整数指针 int (*f5)();返回整数的函数指针 int * (*f6)();返回整 ...
- 《深入理解C指针》
<深入理解C指针> 基本信息 原书名:Understanding and using C pointers 作者: (美)Richard Reese 译者: 陈晓亮 丛书名: 图灵程序设计 ...
- 深入理解C指针----学习笔记
深入理解C指针 第1章 认识指针 理解指针的关键在于理解C程序如何管理内存,指针包含的就是内存地址. 1.1 指针和内存 C程序在编译后,以三种方式使用内存: 1. 静态. ...
- C指针的这些使用技巧,掌握后立刻提升一个Level
这是道哥的第016篇原创 关注+星标公众号,不错过最新文章 目录 一.前言 二.八个示例 1. 开胃菜:修改主调函数中的数据 2. 在被调用函数中,分配系统资源 2.1 错误用法 2.2 正确用法 3 ...
- C#与C/C++的交互zz
C#与C++交互,总体来说可以有两种方法: 利用C++/CLI作为代理中间层 利用PInvoke实现直接调用 第一种方法:实现起来比较简单直观,并且可以实现C#调用C++所写的类,但是问题是MONO构 ...
随机推荐
- Xamarin.Android开发实践(五)
原文:Xamarin.Android开发实践(五) 一.服务的生命周期 服务与活动一样,在它的整个生命周期中存在着一些事件,下图可以很好解释整个过程以及涉及到的方法: 在真实的使用中,Service来 ...
- Unable to connect to your virtual device!解决方法
使用Genymotion安卓模拟器的用户,很多朋友在启动安卓系统的时候就弹出了以下英文,不知道如何处理,今天电脑知识网小编来教您处理Genymotion安卓模拟器启动出错的问题. Error Unab ...
- python中的有趣用法
本文给除了python中几个有趣的用法,可以给我们不一样的启发 1: Python中模拟使用C++ 中的 cout << import sys class ostream: def ...
- XCode 6 出现 no identity found: Command /usr/bin/codesign failed with exit code 1 解决方法汇总
1, 解决办法,进入开发者账号重建一个 Provisioning Profiles(或配套证书) 文件,把证书添加正确就可以了 (应该是最有效的) 2, 将p12文件重新安装下 3, 在 iPhone ...
- CentOS 6 用SVN自动提交文件到web服务器
关于 svn 的安装 参考:[转]Linux(centOS6.5)下SVN的安装.配置及开机启动 经过两天的各种尝试总算解决了,总结如下: 1.在建立库时注意 要让库的名称和 要同步的 web目录名 ...
- instanceof 变量是否属于某一类 class 的实例
<?phpclass MyClass{} class NotMyClass{}$a = new MyClass;$b = new NotMyClass;var_dump($a instanceo ...
- Linux 下github的使用
*初始化git仓库,使用git init命令 *添加文件到git仓库分两步: 1.使用git add filename :可分多次使用,添加多个文件到暂存区 2.使用git commit -m “ ...
- fancyBox简单入门
1. 下载 fancyBox,解压后根据需要将文件复制到网页文件夹中(建议不要更改目录结构),并在网页源码中引入相应的 css 样式和 js 文件(如果更改了目录结构,引入的时候请调整相应代码,对应它 ...
- Main方法的执行过程(转)
要运行一个 main 方法 , 首先要知道 main 方法所在的 Class, 在命令行中指定这个 Class 名 Class Lava{ Private int speed = 4; Void fl ...
- URAL 1820. Ural Steaks(数学啊 )
题目链接:space=1&num=1820" target="_blank">http://acm.timus.ru/problem.aspx? space ...