C#调用C++回调函数

myminimouse 2010-04-02 03:01:20
c++函数

typedef void(*pGetInfoFv)(const char *const Id,const char Color,const unsigned short Code,const char rCode );
void RegGetInfoFv( pGetInfoFv pFv );

我在c#里写

[DllImport("TestDLL.dll", ExactSpelling=true, CharSet=CharSet.Ansi, SetLastError=true)]
public static extern void RegGetInfoFv(RegGetInfoFvCallBack n_RegGetInfoFvCallBack );
public delegate void RegGetInfoFvCallBack (string Id,Int16 Color,ushort Code,Int16 rCode );
public static RegGetInfoFvCallBack g_RegGetInfoFvCallBack+= new RegGetInfoFvCallBack (pFunc);

public static void pFunc(string Id,Int16 Color,ushort Code,Int16 rCode )
{
//do something
}

但是触发不了pFunc函数,不知道是不是数据类型对不上,请大家帮忙看看
...全文
533 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
soaringbird 2010-04-11
  • 打赏
  • 举报
回复
那个color和rcode应该用byte
mfc28jacy 2010-04-08
  • 打赏
  • 举报
回复
顶楼主 多发技术帖
myminimouse 2010-04-08
  • 打赏
  • 举报
回复
无论如何,谢谢xingyuebuyu了
andybang1981 2010-04-07
  • 打赏
  • 举报
回复
应该是数据类型不匹配,我也遇到过这样的问题,程序运行3次是正常的,第4次就报错,真没见过
后来对方给了函数原型就正常了
myminimouse 2010-04-07
  • 打赏
  • 举报
回复
To xingyuebuyu

这个是调用的dll收到socket数据后自动执行的方法,没有任何信息.
我用抓包工具看过,数据确实收到了。另外dll是没有问题的
myminimouse 2010-04-07
  • 打赏
  • 举报
回复
现在可以确定的是只要一执行回调就会出错,并不是执行一次之后,郁闷了
xingyuebuyu 2010-04-07
  • 打赏
  • 举报
回复
函数和回调都使用Cdecl方式再试试
myminimouse 2010-04-07
  • 打赏
  • 举报
回复
To xingyuebuyu:
现在改成

[DllImport("TestDLL.dll", ExactSpelling=true, CharSet=CharSet.Ansi, SetLastError=true)]
public static extern void RegGetInfoFv(RegGetInfoFvCallBack n_RegGetInfoFvCallBack );
public delegate void RegGetInfoFvCallBack (string Id,Int16 Color,ushort Code,Int16 rCode );


public static RegGetInfoFvCallBack g_RegGetInfoFvCallBack = new RegGetInfoFvCallBack (pFunc);
RegGetInfoFv(RegGetInfoFvCallBack);


public static void pFunc(string Id,Int16 Color,ushort Code,Int16 rCode )
{
//do something
}


这样是可以执行了,和你发的链接的现象一样,执行一次后面就报错,弹出未处理的win32异常
myminimouse 2010-04-07
  • 打赏
  • 举报
回复
To xingyuebuyu:
是一样的,不过我都没有执行。

我看下他怎么写的
xingyuebuyu 2010-04-06
  • 打赏
  • 举报
回复
RegGetInfoFv和pGetInfoFv是以什么方式导出的?_stdcall还是_cdecl?
C++默认是_cdecl,.net默认是_stdcall调用,如果不是需要修改CallingConvention为相应的方式。

            [DllImport("TestDLL.dll",CallingConvention=CallingConvention.StdCall, ExactSpelling=true, CharSet=CharSet.Ansi, SetLastError=true)]
public static extern void RegGetInfoFv(RegGetInfoFvCallBack n_RegGetInfoFvCallBack );

[System.Runtime.InteropServices.UnmanagedFunctionPointer(CallingConvention=CallingConvention.StdCall)]
public delegate void RegGetInfoFvCallBack (string Id,byte Color,ushort Code,byte rCode );
public static RegGetInfoFvCallBack g_RegGetInfoFvCallBack+= new RegGetInfoFvCallBack (pFunc);

public static void pFunc(string Id,byte Color,ushort Code,byte rCode )
{
//do something
}
myminimouse 2010-04-06
  • 打赏
  • 举报
回复
还是不行,请大家帮忙再看下
xingyuebuyu 2010-04-06
  • 打赏
  • 举报
回复
不行是什么意思?回调函数不执行吗?有没有错误信息?
myminimouse 2010-04-06
  • 打赏
  • 举报
回复
改了2005还是不行,郁闷了
ChrisAK 2010-04-06
  • 打赏
  • 举报
回复
其实一条非托管函数转成托管函数可以有很多种写法.
只要保证:

调用规则无误;
传入的传出的普通参数长度无误,指针类参数指向的内存区域无误且够大.
ChrisAK 2010-04-06
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 myminimouse 的回复:]
To ChrisAK:
谢谢,我试一下

问一下c++ char的类型在c#里你写的sbyte,我查一下有说byte的还有int16的,这个会不会有问题呢
[/Quote]第一个我不确定是不是字符串,因为只有0结尾的字符串才能被转为string,如果确认它是字符串
的话当然能用string.C++下的char就是byte占一个字节.说是int16估计是和宽字符弄混了.
wchar_t也是字符,用来表示使用长字符的Unicode字符串的.每个占2byte

另外1.1我还真没办法...考虑换2.0吧╮(╯_╰)╭.
myminimouse 2010-04-06
  • 打赏
  • 举报
回复
[System.Runtime.InteropServices.UnmanagedFunctionPointer(CallingConvention=CallingConvention.StdCall)]

这个在1.1里是怎么写呢?
myminimouse 2010-04-06
  • 打赏
  • 举报
回复
还有第一个参数类型,你写的ref sbyte,不是string吗
myminimouse 2010-04-06
  • 打赏
  • 举报
回复
To ChrisAK:
谢谢,我试一下

问一下c++ char的类型在c#里你写的sbyte,我查一下有说byte的还有int16的,这个会不会有问题呢
ChrisAK 2010-04-06
  • 打赏
  • 举报
回复
另外RegGetInfoFv可能也要改成Cdecl,因为从原型看没有指明使用stdcall.
加载更多回复(15)

110,535

社区成员

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

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

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