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 == )
{
return false;
} FunSet(GetFunTable());
return true;
}
//-关闭DLL---
public bool Close()
{
return FreeLibrary(Hand)!=;
}
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 = ; //DLL的句柄
private static Delegate GetAddress(int dllModule, string functionname, Type t) //把指针转变成C#的代理
{
int addr = GetProcAddress(dllModule, functionname);
if (addr == )
{
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 = ; i < aFun.Length; i++)
{
Value = aFun[i].Split(','); //"Box, TBox, _Box" 第一项是代理的实例名,第二项是代理的定义名,第三项是DLL中的函数名
if (Value.Length == )
{
FieldInfo fi = tp.GetField(Value[].Trim()); //找实例
Type type = tp.GetNestedType(Value[].Trim());//找尾托
if (fi != null && type != null)
{
fi.SetValue(this, GetAddress(Hand, Value[].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()[]; //第一个对应的名字空间当成是调用的名字空间
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;
} }

C#调用C++回调函数的问题的更多相关文章

  1. [Effective JavaScript 笔记]第67条:绝不要同步地调用异步的回调函数

    设想有downloadAsync函数的一种变种,它持有一个缓存(实现为一个Dict)来避免多次下载同一个文件.在文件已经被缓存的情况下,立即调用回调函数是最优选择. var cache=new Dic ...

  2. DLL与EXE之间的通讯调用 以及 回调函数的线程执行空间

    dll 与 exe 之间的通讯方式有很多种, 本文采用回调函数的方法实现, 本文也将研究多线程,多模块的情况下,回调函数所在的线程, 啥也不说了,先附上代码: 下面的是dll模块的的, dll的工程文 ...

  3. setInterval调用ajax回调函数不执行的问题

    setInterval调用ajax回调函数不执行 1.首先检查你的setInterval()函数写法是否正确 参考写法 // 检查是否支付成功 var isPayRequest=false; var ...

  4. 理解 JavaScript 回调函数并使用

    JavaScript中,函数是一等(first-class)对象:也就是说,函数是 Object 类型并且可以像其他一等对象(String,Array,Number等)一样使用.它们可以"保 ...

  5. VC++ 回调函数及使用方法(转)

    转载:http://blog.csdn.net/vsooda/article/details/7435801 转载:http://blog.csdn.net/lincyang/article/deta ...

  6. Mina、Netty、Twisted一起学(九):异步IO和回调函数

    用过JavaScript或者jQuery的同学都知道,JavaScript特别是jQuery中存在大量的回调函数,例如Ajax.jQuery的动画等. $.get(url, function() { ...

  7. js中的回调函数的理解和使用方法

    js中的回调函数的理解和使用方法 一. 回调函数的作用 js代码会至上而下一条线执行下去,但是有时候我们需要等到一个操作结束之后再进行下一个操作,这时候就需要用到回调函数. 二. 回调函数的解释 因为 ...

  8. JS回调函数(callback)

    在使用Jquery的时候,用到Callback(),回调函数的概念.而且很多. 比如: $.ajax({ url:"test.json", type: "GET" ...

  9. C#将C++动态库的回调函数封装成事件

    关于C#调用C++动态库的文章很多,调用动态库中回调函数的方法也不在少数.但大多数调用回调函数的方法依然保留了C++的语法特点. 比如有一段C++的回调函数代码,为了表达它的意思,我把注释也粘贴了进来 ...

随机推荐

  1. IP地址库

    吐槽 前两天一个线上的IP地址库除了点幺蛾子,一查代码,发现用的库早就不更新了,遂决定换库,有几个方案: 纯真数据库 IPIP数据库 GeoIP 纯真数据库是大码农的福音,免费,但是精度一般:IPIP ...

  2. Scala学习2 ———— 三种方式完成HelloWorld程序

    三种方式完成HelloWorld程序 分别采用在REPL,命令行(scala脚本)和Eclipse下运行hello world. 一.Scala REPL. 按照第一篇在windows下安装好scal ...

  3. 如何正确从windows系统(自己电脑)远程访问Linux系统(他人电脑)的mysql数据库(图文详解)

    这里,需要Linux系统开了root用户,我这给root用户密码为root.     同时,在mysql -uroot -proot执行进去之后 update user setHost='%' whe ...

  4. python--6、logging模块

    logging 可用的日志级别: debug 10 info 20 warning 30 error 40 critical 50 logging默认参数: 默认日志级别是warning. 默认情况日 ...

  5. IVVI SK3-02小骨酷派SK3-02 进入第三方 recovery 刷机 ROOT

    首先下载好工具:http://url.cn/5AS7IiB 备用连接 :https://pan.baidu.com/s/1jJmbYAi 本篇教程教你如何傻瓜式解锁BootLoader并进入临时rec ...

  6. ★Java语法(四)——————————运算符

    使用除法“/”  ,要特别注意数据类型的问题.若被除数和除数都是整形,且被除数不能被除数整除时,这时输出的结果为整数,(即整形数/整形数=整形数),这是因为整形变量无法保存小数点后面的数据所致,要特别 ...

  7. ★Java-----记事本编译、运行时注意事项

    1.文件名需要与源代码中公共类的名字相同,即class后面的名字: 2.Java中严格区分大小写: 3.记事本编辑好之后保存文件后缀必须是". java": 4.运行cmd,dos ...

  8. ASP.NET刷新页面的六种方法

    第一: private void Button1_Click( object sender, System.EventArgs e )   {      Response.Redirect( Requ ...

  9. 图像局部显著性—点特征(SiftGPU)

    SIFT的计算复杂度较高. SiftGpu的主页:SiftGPU: A GPU Implementation of ScaleInvariant Feature Transform (SIFT) 对S ...

  10. c#同步锁Monitor.Enter(T)

    protected static object MObjLock = new object();//同步锁 public string GetData(int mId) { Monitor.Enter ...