程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#調用C++回調函數的問題

C#調用C++回調函數的問題

編輯:關於C語言

C++的回調函數中有一個參數是,是返回一個字符串,原則如下:

typedef  void  (*TDataEvent)(char  *AData  ,int  ALen);

其中char *AData是從DLL中返回一個字符串,串的內存已經在DLL中分配了

下面中我在C#中定義的委托

public delegate void TDataEvent(Byte[] AData,  int ALen);

下面是回調函數的設置代碼:

Event=new clReceivelDllPoxy.TDataEvent(getDate);

ReceDllPoxy.AddServer(1024,Event,2);

其中Event是上面委托的實例,我定義成一個成員這樣就不會被自己釋放

下面是C#中回調函數的實現

public void getDate(byte[] AData,int ALen)
{
//發現每次回調是  AData只有一個字節
}

下面轉載一個別人的代碼,謝謝

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Reflection.Emit;
namespace AppDllTest
{
  /**//// <summary>
  /// 非托管動態調用基類,基類不能直接使用,需要實現 FunTable()的虛函數
  /// </summary>
  public abstract class clDllBasePoxy
  {
    //-裝入DLL---------
    public bool Open(string dllFileName)
    {
      Hand = LoadLibrary(dllFileName);
      if (Hand == 0)
      {
        return false;
      }
      FunSet(GetFunTable());
      return true;
    }
    //-關閉DLL---
    public bool Close()
    {
      return FreeLibrary(Hand)!=0;
    }
    public abstract string[] GetFunTable(); //函數對應表由外部代理類通過 GetFunTable來設置
    //調用Windows32下的Kernele32庫中的裝入函數來完成對非托管DLL的引用-------#region //調用Windows32下的Kernele32庫中的裝入函數來完成對非托管DLL的引用-------
    //--------------------------------------------------------------
    [DllImport("Kernel32")]
    private static extern int GetProcAddress(int handle, String funcname);
    [DllImport("Kernel32")]
    private static extern int LoadLibrary(String funcname);
    [DllImport("Kernel32")]
    private static extern int FreeLibrary(int handle);
    private int Hand = 0; //DLL的句柄
    private static Delegate GetAddress(int dllModule, string functionname, Type t) //把指針轉變成C#的代理
    {
      int addr = GetProcAddress(dllModule, functionname);
      if (addr == 0)
      {
        return null;
      }
      else
      {
        return Marshal.GetDelegateForFunctionPointer(new IntPtr(addr), t);
      }
    }
    //--關聯代理和DLL中的函數-----------
    private bool FunSet(string[] aFun)
    {
      Type tp = this.GetType();
      string[] Value;
      for (int i = 0; i < aFun.Length; i++)
      {
        Value = aFun[i].Split(','); //"Box, TBox, _Box" 第一項是代理的實例名,第二項是代理的定義名,第三項是DLL中的函數名
        if (Value.Length == 3)
        {
          FieldInfo fi = tp.GetFIEld(Value[0].Trim()); //找實例
          Type type = tp.GetNestedType(Value[1].Trim());//找尾托
          if (fi != null && type != null)
          {
            fi.SetValue(this, GetAddress(Hand, Value[2].Trim(), type)); //創建關聯
          }
        }
      }
      return true;
    }
    #endregion
  }
  public class clDllPoxy : clDllBasePoxy
  {
    public override string[] GetFunTable()
    {
      string[] FunTable = new string[]{
      "GetFixParamCount, TGetFixParamCount, _GetFixParamCount",
      "GetFixParam, TGetFixParam, _GetFixParam"
      };
      return FunTable;
    }
    //--輸出函數----------------------------------------------
    public TGetFixParamCount GetFixParamCount;
    public TGetFixParam GetFixParam;
    //--代理描述----------------------------------------------
    public delegate int TGetFixParamCount();           //獲取固定參數個數
    public delegate bool TGetFixParam(int AIndex, byte []AOutBuf); //固定參數
  }
  
  /**//// <summary>
  /// C#動態調用托管DLL的基類--------------
  /// </summary>
  public class clNetDllPoxy
  {
    //--裝入動態庫----------
    public bool Open(string dllFileName, string className)
    {
      FAsembly = Assembly.LoadFrom(dllFileName);
      if (FAsembly == null)
      {
        return false;
      }
      Type type = FAsembly.GetTypes()[0]; //第一個對應的名字空間當成是調用的名字空間
      FDllName = dllFileName;
      FClassName = className;
      if (type != null)
      {
        FNameSpace = type.Namespace;
      }
      return true;
    }
    //--設置Dll中的函數范圍---------
    public void SetArea(string nameSpace, string className)
    {
      FNameSpace = nameSpace;
      FClassName = className;
    }
    //--調用指定的方法,注:方法的所有參數都轉化成對象類型
    public object Invoke(string funName, object[] ObjArray_Parameter)
    {
      try
      {
        Type[] types = FAsembly.GetTypes();
        foreach (Type tp in types)
        {
          if (tp.Namespace == FNameSpace && tp.Name == FClassName)
          {
            MethodInfo metInfo = tp.GetMethod(funName);
            if (metInfo != null)
            {
              object obj = Activator.CreateInstance(tp); //創建類對象
              if (obj != null)
              {
                return metInfo.Invoke(obj, ObjArray_Parameter);
              }
            }
          }
        }
      }
      catch
      { }
      return null;
    }
    private Assembly FAsembly; //Dll的程序集
    private string FDllName;
    private string FNameSpace;
    private string FClassName;
  }
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved