c#调用回调函数含结构体问题

jinxuliang 2010-06-18 09:53:47
C++封装的结构体与函数形式如下:

typedef struct _DS_INFO{
DWORD apid;
WORD hwid;
WORD flag;
DWORD real_ip_addr;
DWORD pseudo_ip_addr;
DWORD host_ip_addr;
BYTE mac[MACLEN];
}DS_INFO, *PDS_INFO;

到处DLL:
IMPORT_EXPORT int SDKCI_FUNC dsc_EnumSearch(DWORD server_ip, WNDENUMSEARCHPROC lpenumproc);

typedef int (CALLBACK* WNDENUMSEARCHPROC)(PDS_INFO);


我对应的C#转换调用形式如下:


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DS_INFO
{
public uint apid;
public ushort hwid;
public ushort flag;
public uint real_ip_addr;
public uint pseudo_ip_addr;
public uint host_ip_addr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] mac;
}

public delegate int ProcessDelegate(ref DS_INFO dsinfo);

[DllImport(".\\NECI.dll",CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
unsafe public static extern int dsc_EnumSearch(uint server_ip, ProcessDelegate lpenumproc);

int EnumSearchProc( ref DS_INFO dsinfo)
{
Trace.WriteLine("call back ");
}

程序调用部分:
try
{
ProcessDelegate newCallproc = new ProcessDelegate(EnumSearchProc);
int ret = dsc_EnumSearch(0xffffffff, newCallproc);
}
catch(Exception ex)
{
throw ex;//System.ArgumentNullException 中第一次偶然出现的“未知模块”类型的异常
}
/////////////////
请问我上述封装有什么问题?DLL可以确定没有任何问题。有意帮忙调试的大侠,请留下EMAIL。
...全文
332 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
jinxuliang 2010-06-20
  • 打赏
  • 举报
回复
非常感谢MSDN论坛的kiddowong帮我解决了。
public delegate int ProcessDelegate(ref DS_INFO dsinfo);

改为

public delegate int ProcessDelegate(System.IntPtr dsinfo);

之后用Marshal.PtrToStructure

在回掉函数里将Ptr转换为对应的结构体或者结构体数组。

jinxuliang 2010-06-20
  • 打赏
  • 举报
回复
万能的主!我继续顶!高人出招。分可以再加!哭泣...
兔子-顾问 2010-06-19
  • 打赏
  • 举报
回复
ProcessDelegate newCallproc = new ProcessDelegate(EnumSearchProc);
你声明在类中,声明为静态字段,应该可以。
灵雨飘零 2010-06-19
  • 打赏
  • 举报
回复
帮顶

兔子-顾问 2010-06-19
  • 打赏
  • 举报
回复
wuyazhe@yeah.net
jinxuliang 2010-06-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 wuyazhe 的回复:]
ProcessDelegate newCallproc = new ProcessDelegate(EnumSearchProc);
你声明在类中,声明为静态字段,应该可以。
[/Quote]
你的意思是这样吗?
static int EnumSearchProc( ref DS_INFO dsinfo)
{
Trace.WriteLine("call back ");
}

int ret = dsc_EnumSearch(0xffffffff, EnumSearchProc);

依然提示同样的错误。去掉异常捕获,错误行就在dsc_EnumSearch。
请大侠指点。
要不留个EMAIL给我,发给你帮我看看,谢谢。
兔子-顾问 2010-06-19
  • 打赏
  • 举报
回复
看了。不知道如何弄。抱歉。
jinxuliang 2010-06-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 wuyazhe 的回复:]
wuyazhe@yeah.net
[/Quote]
已发邮件!请查收。非常感谢!
兔子-顾问 2010-06-18
  • 打赏
  • 举报
回复
稍等一下,别急。这是论坛,不是qq群。在忙。一会有空了来给你写个范例告诉你如何修改可以尝试解决问题。
  • 打赏
  • 举报
回复
不感兴趣c++问题。
jinxuliang 2010-06-18
  • 打赏
  • 举报
回复
没人气???
1. 连接oracle时,目录中不能有()字符,否则ADO是无法连接数据库的 修改: 2.1 去掉TCPChannel的BuildPacket函数,改成直接由OnRecv回调函数返回实际数据 去掉UDPChannel的Response函数,改成直接由内部处理 2.2 修改TCPChannel类,实现同步调用接口 定义IRPC接口用来处理同步调用的被调用端 定义Bind函数用来绑定IRPC接口的实例 定义CallEx函数用来实现用户同步调用 2.3 添加bInit变量,用于设置初始化和关闭状态。 设置此变量的目的主要是用来控制,在关闭了socket之后,后续的任何投递都不执行。 修改了IRPC接口名称为IRemoteProcCall,并且调整了部分结构体名称,如RPC相关的结构体, 组合包相关的结构体,以及P2P相关的结构体。 修改TCPChannel类的接口函数Bind成BindEx,使之与TCPChannel的其他接口统一命名。 修改测试Demo,添加多发选项 修改DataType.h中的内存块大小定义 封装临界区类,信号量类 修改TCPListener接口类中的EnumSockets接口,添加pArg参数 Socket类添加ReUseAddr函数,用来设置端口重用 TCPSocket接口类添加GetListener接口用来获得链接管理对象 修改Demo实例中的TCP客户端部分,增加可更改客户端连接数 2.4 添加UDT支持 修改UDPChannel接口类,添加UDT支持接口函数 添加日志支持 添加接口类ILogger,用来实现对日志的输出 添加x64的编译环境 添加部分WARN级别的日志输出 添加C接口,方便非C++语言应用 UDT添加特性,关闭UDT时,给对端发送断线信息,通知对端断线 UDT提高效率,UDT句柄部分改用读写锁来控制,以提高效率 修改OnSend和OnSendTo的行为 修改过的BUG: 1. 数据发送时,如果数据大小正好是MAX_PACKET_SIZE个字节的话,数据发送不出去,在计算包大小时,边界值没处理好。 2. IOCPUnhandledException函数内部逻辑错误,没有关联到自己的异常处理函数中,导致即使调用成功,程序异常了,也无法写dump文件。 3. 修复IOCP UDP Release模式下不能正常运行的BUG。由于传递的输出参数使用了局部变量导致的问题 4. 修复UDT发送时,计算尾包大小错误 5. 修复UDT快速发送错误 6. 修改Queue关闭时,如果有线程正在等待信号,会导致线程死等

110,539

社区成员

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

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

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