zoukankan      html  css  js  c++  java
  • 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来设置
    
            #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;
        }
        
    }
  • 相关阅读:
    设计模式六大原则【转】
    2进制中1的个数
    最大子数组和
    八皇后问题
    读取tomcat下的文件夹路径
    <![CDATA[ ]]>
    数据库(第一范式,第二范式,第三范式)
    input设置disabled,经过strus2提交到后台,后台取不到值
    下载项目乱码
    jsp与Action值得对应
  • 原文地址:https://www.cnblogs.com/jordan2009/p/3696321.html
Copyright © 2011-2022 走看看