C#c++伝達関数ポインタ

4272 ワード

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
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