代码改变世界

c#,委托,回调,事件,系列,一,

2008-06-03 22:55  Virus-BeautyCode  阅读(2428)  评论(2编辑  收藏  举报

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的引用-------
    }


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

    
}