c#调用sdk时,求教回调函数如何处理

aresdengliujun 2010-12-16 03:03:10
我现在需要调用一个设备的sdk,里面有个函数用了回调函数,我查了些资料,也用了委托,可能我写错了,
不知道如何才能取得函数返回的数据。
函数如下:
int __stdcall tltmStartReadingItems(HANDLE hHandle, unsigned int uiFieldsMask, BOOL boSetEAS,
void (__stdcall *lpfnRawCallBack)(HANDLE hHandle, int iReasonForCall, struct tltmRawItem *myRawItem, void *pParam),
void (__stdcall *lpfnCallBack)(HANDLE hHandle, int iReasonForCall, struct tltmItem *myItem, void *pParam), void *pParam)

哪位大哥指点一下小弟,谢谢!
...全文
830 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
jinru2560 2010-12-29
  • 打赏
  • 举报
回复
委托
public delegate bool CallBack(int hwnd, int lParam);
aresdengliujun 2010-12-29
  • 打赏
  • 举报
回复
AbstractReader的定义看不到,另外TAGSYSLP101 根本就不需要继承,回调函数声明中直接用AbstractReader

按照上面的改了没有报错了,但是回调函数还是没有被执行,会不会还是参数不对的原因呢?
把数据结构改成类会不会好一些?
aresdengliujun 2010-12-29
  • 打赏
  • 举报
回复
谢谢楼上的回答,请问这个数据结构怎么实例化?
回调函数是自动转换的,不知道如何去实例化,请指教。

jhabb 2010-12-28
  • 打赏
  • 举报
回复
我也遇到过这样的问题 我是封装了一个中间dll 解决的
xingyuebuyu 2010-12-28
  • 打赏
  • 举报
回复
AbstractReader的定义看不到,另外TAGSYSLP101 根本就不需要继承,回调函数声明中直接用AbstractReader

回调函数当中有数据结构作为参数,在回调的时候,会不会因为没有提前实例化而出错呢?

回调函数当中有数据结构作为参数要看DLL中是否有对这个参数作过什么处理,最好是先实例化
aresdengliujun 2010-12-28
  • 打赏
  • 举报
回复
//dll调用的类:tagsys
//回调函数
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void lpfnRawCallBack(IntPtr hHandle, Int16 iReasonForCall, ref Tagsys.tltmRawItem myRawItem, TAGSYSLP101 pParam);

public class Tagsys
{
。。。。。。

//// Raw Reading
//int __stdcall tltmStartReadingRawItems(HANDLE hHandle, unsigned int uiFieldsMask, BOOL boSetEAS, void (__stdcall *lpfnRawCallBack)(HANDLE hHandle, int iReasonForCall, struct tltmRawItem *myRawItem, void *pParam), void *pParam);
[DllImport(ReaderList.READERS_TAGSYS_DLL, EntryPoint = "tltmStartReadingRawItems", CharSet=CharSet.Ansi, ExactSpelling=false,CallingConvention=CallingConvention.StdCall)]
public static extern int tltmStartReadingRawItems(IntPtr hHandle, uint uiFieldsMask, Boolean boSetEAS,lpfnRawCallBack lpfnRawCallBack, TAGSYSLP101 pParam);

}

//实际应用:
public unsafe class TAGSYSLP101 : AbstractReader
{
public TAGSYSLP101()
{
lpfnRawCallBack myRawCallBk = new lpfnRawCallBack(TAGSYSLP101.myRawCallBack);

intErr = Tagsys.tltmStartReadingRawItems(this.m_device_handle, Tagsys.TLTM_ITEM_ALL, false, myRawCallBk, this);

}

public static void myRawCallBack(IntPtr hHandle, Int16 iReasonForCall, ref Tagsys.tltmRawItem myRawItem, TAGSYSLP101 pParam)
{
Console.WriteLine("here myRawCallBack");
}
}

麻烦帮我看看对不对。

另外,回调函数当中有数据结构作为参数,在回调的时候,会不会因为没有提前实例化而出错呢?
public static void myRawCallBack(IntPtr hHandle, Int16 iReasonForCall, ref Tagsys.tltmRawItem myRawItem, TAGSYSLP101 pParam)
aresdengliujun 2010-12-27
  • 打赏
  • 举报
回复
自己顶以下,有高手请指点一下
xingyuebuyu 2010-12-27
  • 打赏
  • 举报
回复
你的class的代码贴出来看看,怎么和ComVisible扯上关系了
aresdengliujun 2010-12-24
  • 打赏
  • 举报
回复
经过测试,抛了InvalidOperationException异常:

此类型的层次结构中有 ComVisible(false)父级,因此不允许 QueryInterface 调用 IDispatch 或类接口。

这个异常的资料很少,我把ComVisible改成true也不行
xingyuebuyu 2010-12-23
  • 打赏
  • 举报
回复
public static void myCallBack(IntPtr hHandle, int iReasonForCall, ref Tagsys.tltmItem myRawItem, class1 pParam)

tltmStartReadingItems(m_hHandle, uiFields, boSetEAS, myRawCallback, myCallback, this);

最后一个参数直接传你要的class类型试试,class1 是this代表的class类型,让编译器自己去进行地址转换


flyerwing 2010-12-23
  • 打赏
  • 举报
回复
是plateform API吧
aresdengliujun 2010-12-23
  • 打赏
  • 举报
回复

this代表的是class

C++的示例代码里面是这样写的

tltmStartReadingItems(m_hHandle, uiFields, boSetEAS, myRawCallback, myCallback, this);

void __stdcall myRawCallback(HANDLE hHandle, int iReasonForCall, tltmRawItem *myItem, void *pParam)
{
。。。。
}

void __stdcall myCallback(HANDLE hHandle, int iReasonForCall, tltmItem *myItem, void *pParam)
{
。。。。
}
xingyuebuyu 2010-12-22
  • 打赏
  • 举报
回复
你的this指针代表的是class还是struct,声明的代码贴出来看看

最坏状况是再写个DLL将这个DLL封装起来,提供一个去掉this指针的回调函数
aresdengliujun 2010-12-22
  • 打赏
  • 举报
回复
还是没有办法取得this的内存地址,完蛋了
aresdengliujun 2010-12-22
  • 打赏
  • 举报
回复
试过了,不可以
抛下面的异常:
System.ArgumentException:Object 包含非基元或非直接复制到本机结构中的数据

看来只有通过别的方法取得当前实例的内存地址了。
不能回调的话就郁闷了


aresdengliujun 2010-12-22
  • 打赏
  • 举报
回复
谢谢,我测试一下
lixinrande 2010-12-21
  • 打赏
  • 举报
回复
lpfnCallBack用
public static void myCallBack(IntPtr hHandle, int iReasonForCall, ref Tagsys.tltmItem myRawItem, IntPtr pParam)
lixinrande 2010-12-21
  • 打赏
  • 举报
回复
回调函数用.NET中的委托处理
xingyuebuyu 2010-12-21
  • 打赏
  • 举报
回复
            System.Runtime.InteropServices.GCHandle gh = System.Runtime.InteropServices.GCHandle.Alloc(this, System.Runtime.InteropServices.GCHandleType.Pinned);
IntPtr pParam = gh.AddrOfPinnedObject();
intErr = tltmStartReadingRawItems(this.m_handle, 1, 0, rawBk, pParam);
gh.Free();


这样试试看能成功否获取到this的指针
  • 打赏
  • 举报
回复
看来只有用不安全代码解决了,因为this难办
加载更多回复(10)

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧