VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > C#教程 >
  • c#调用c++的回调函数问题

制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
 

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

 

  http://www.cnblogs.com/virusswb/archive/2008/06/03/1213124.html

 

 

  http://www.cnblogs.com/virusswb/archive/2008/06/03/1213124.html

 



相关教程