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构 ...
随机推荐
- 基于visual Studio2013解决C语言竞赛题之0404循环求和
题目 解决代码及点评 这道题考验for循环和一个简单的算法 因为每次累加的值有规律,后面一次累加是前面一次累加的两倍 所以可以用简单的循环,计算累加项和累加结果 /************ ...
- More Divisors(反素数)
More Divisors Time Limit: 2 Seconds Memory Limit: 65536 KB Everybody knows that we use decimal ...
- Windows下搭建deepnet环境
近期在做deep learning的项目,学习了一下deepnet,之前搭建了一个windows下的deepnet的学习开发环境,把搭建系统的过程分享给大家. 1.我用的是windows下的visua ...
- 【转】URL和URI的区别
[转]URL和URI的区别 译者:华科小涛:http://www.cnblogs.com/hust-ghtao/: 初学http协议,就被这两个相似的术语搞蒙了,查了很多资料,总算搞清楚了.(找资料还 ...
- 【Oracle】不安装Oracle客户端直接用PL/SQL连接数据库
1.下载 instantclient_11_2.zip PL/SQL2.解压instantclient_11_2.zip到相应文件夹,比如:E:\oracleclient\instantclient_ ...
- 打印NSLog分类 Foundation+Log.m
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @implementation UIView(Log) + ...
- python成长之路——第二天
cpython:c解释器 .pyc(字节码)——机器码 jpython :java解释器 java字节码 ironpython :C#解释器 C#字节码 .... 上面的:编译完之后 ...
- 浙江工商大学15年校赛I题 Inversion 【归并排序求逆序对】
Inversion Time Limit 1s Memory Limit 131072KB Judge Program Standard Ratio(Solve/Submit) 15.00%(3/20 ...
- HDU 5119 Happy Matt Friends(2014北京区域赛现场赛H题 裸背包DP)
虽然是一道还是算简单的DP,甚至不用滚动数组也能AC,数据量不算很大. 对于N个数,每个数只存在两个状态,取 和 不取. 容易得出状态转移方程: dp[i][j] = dp[i - 1][j ^ a[ ...
- scrapy入门
安装完scrapy后,创建一个新的工程: scrapy startproject tutorial 会创建一个tutorial文件夹有以下的文件: tutorial/ scrapy.cfg tutor ...