歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C# C++ 傳遞函數指針

C# C++ 傳遞函數指針

日期:2017/3/1 9:53:12   编辑:Linux編程

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++中使用模板傳遞函數類型 http://www.linuxidc.com/Linux/2012-11/73809.htm

Copyright © Linux教程網 All Rights Reserved