C#c++伝達関数ポインタ
4272 ワード
C#とc++間の相互伝達関数ポインタ
C++とC#の中にはcallback methodがたくさんありますが、お互いに呼び出すことができますか?どのように伝えるかは、私のいとこの問題です.
1.c++dllの定義、エクスポート方法
//sort.cpp:DLLアプリケーションのエクスポート関数を定義します.//
エクスポートファイルsortを定義します.def
LIBRARY BTREE
EXPORTS fnsort
今、私たちはc#がfnsortを呼ぶことができることを期待して、funccsharpを実現してソートアルゴリズムを実現して、c#の中でLoadLibrary、GetProcAddress、FreeLibraryはもちろん少なくありません.また、インタフェースを定義してcompareを実現し、2つのconst void*を転送し、intを転送する.
委任の定義
int(_cdecl*compare)(const void*elem 1,const void*elem 2)を実現したと考えられる.今は大丈夫だ順調だマーシャルGetDelegteForFunctionPointerは1つのintptrを1つの依頼に変換し、new delegate(pfunc)は1つのcsharp funcを1つの関数ポインタに変換してcppを描画することができ、前例に従って、完全に実現する.
出力は次のとおりです.
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
array length:"<<size<<"\r
";
std::cout << "entry fnsort in cpp\r
";
for(int index=0; index<size;index++){
std::cout << arr[index] << " ";
}
qsort(arr,size,sizeof(int),fuccsharp);
std::cout<<"\r
sort end\r
";
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を実現し、2つの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*elem 1,const void*elem 2)を実現したと考えられる.今は大丈夫だ順調だマーシャルGetDelegteForFunctionPointerは1つのintptrを1つの依頼に変換し、new delegate(pfunc)は1つのcsharp funcを1つの関数ポインタに変換して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
end");
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