|
问题:在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
{
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
以上文章来自凌阳嵌入式培训 网,推荐阅读:javascript:;answer/2013/0730/2038.html