C#调用dll,出现堆损坏的错误

挂在红杏东南枝 2016-01-19 02:38:22
我使用C#去调用一个dll里的回调函数,回调函数的参数是一个结构体指针。运行跑了一遍后,返回的结构体可以拿到值,但是过一会就会出现停止工作的提示,

去事件查看器里看,是说错误模块名称: ntdll.dll,异常代码: 0xc0000374
请问这是为什么,有解决的办法么
...全文
527 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
问题解决了,首先,dll那边我不知道,好像也有点问题,具体改了啥我不知道。 但是C#的问题是出现在回调函数这边,回调函数参数类型应该为IntPtr。
  • 打赏
  • 举报
回复
引用 13 楼 dongxinxi 的回复:
函数内用malloc分配了空间,所以那个字段也不用你管。你那个dll是成熟可靠的吗?想办法联合调试?
用C++,java都有去调用这个dll,他们都没有问题
  • 打赏
  • 举报
回复
函数内用malloc分配了空间,所以那个字段也不用你管。你那个dll是成熟可靠的吗?想办法联合调试?
  • 打赏
  • 举报
回复
引用 10 楼 From_TaiWan 的回复:
[quote=引用 9 楼 qq_31005577 的回复:]
[quote=引用 8 楼 From_TaiWan 的回复:]
能收到结构体信息,说明定义没问题
感觉是内存地址需要固定,这里没有函数的实现,不好判断


函数的实现是指服务器那边代码?[/quote]不是,函数的具体实现应该在GTPAPI.dll里面,C++的dll,我们看不到的,你找找有没有更详细的说明书[/quote]这个么
  • 打赏
  • 举报
回复



引用 10 楼 From_TaiWan 的回复:
[quote=引用 9 楼 qq_31005577 的回复:]
[quote=引用 8 楼 From_TaiWan 的回复:]
能收到结构体信息,说明定义没问题
感觉是内存地址需要固定,这里没有函数的实现,不好判断


函数的实现是指服务器那边代码?[/quote]不是,函数的具体实现应该在GTPAPI.dll里面,C++的dll,我们看不到的,你找找有没有更详细的说明书[/quote][img=https://img-bbs.csdn.net/upload/201601/20/1453255985_763443.png]
秋的红果实 2016-01-19
  • 打赏
  • 举报
回复
引用 9 楼 qq_31005577 的回复:
[quote=引用 8 楼 From_TaiWan 的回复:] 能收到结构体信息,说明定义没问题 感觉是内存地址需要固定,这里没有函数的实现,不好判断
函数的实现是指服务器那边代码?[/quote]不是,函数的具体实现应该在GTPAPI.dll里面,C++的dll,我们看不到的,你找找有没有更详细的说明书
  • 打赏
  • 举报
回复
引用 8 楼 From_TaiWan 的回复:
能收到结构体信息,说明定义没问题 感觉是内存地址需要固定,这里没有函数的实现,不好判断
函数的实现是指服务器那边代码?
秋的红果实 2016-01-19
  • 打赏
  • 举报
回复
能收到结构体信息,说明定义没问题 感觉是内存地址需要固定,这里没有函数的实现,不好判断
  • 打赏
  • 举报
回复
引用 5 楼 dongxinxi 的回复:
如果你用Array,那就用public byte[] caccessID;否则用 [MarshalAs(UnmanagedType.LPStr)] public StringBuilder caccessID = new StringBuilder(20); 第二个不确定,要看那函数怎么用的,也有可能是它直接将你的指针指向另一个已存在的变量(地址)
这是将整个结构体指针作为回调函数的参数 typedef int (* callBack)(CALLBACK_MESSAGE *pcallback_message) ; 这样子
  • 打赏
  • 举报
回复
如果你用Array,那就用public byte[] caccessID;否则用 [MarshalAs(UnmanagedType.LPStr)] public StringBuilder caccessID = new StringBuilder(20); 第二个不确定,要看那函数怎么用的,也有可能是它直接将你的指针指向另一个已存在的变量(地址)
  • 打赏
  • 举报
回复
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] caccessID
  • 打赏
  • 举报
回复
引用 3 楼 dongxinxi 的回复:
对方用的char*又不是TCHAR* [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string caccessID; 你直接用ByValStr, Charset=Ansi就好了,没必要再用TStr了,要不然WinNT上就是Unicode编码了 还有个就是 [MarshalAs(UnmanagedType.LPStr)] public String cpmessage; 不知道那个API函数是否有分配空间,如果没有,那可能需要调用者负责分配和释放
这个这样写么 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public char[] caccessID; 第二个,调用者分配释放要怎么处理?
  • 打赏
  • 举报
回复
对方用的char*又不是TCHAR* [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string caccessID; 你直接用ByValStr, Charset=Ansi就好了,没必要再用TStr了,要不然WinNT上就是Unicode编码了 还有个就是 [MarshalAs(UnmanagedType.LPStr)] public String cpmessage; 不知道那个API函数是否有分配空间,如果没有,那可能需要调用者负责分配和释放
  • 打赏
  • 举报
回复
引用 1 楼 xian_wwq 的回复:
把dll的api定义和dllimport贴一下, 有助于分析问题
FUNCTION_EXPORT int GTPLogin(char* ipList, \char* portList,\char* accessID,\ char* accessPasswd,\char* certificatePath,\char* certificatePasswd,\BREAK_DATA_INFO* breakData\); FUNCTION_EXPORT int GTPMsgRec(char* accessID, callBack pcallBack, callErrorBack pcallErrorBack); FUNCTION_EXPORT int GTPMsgSend(char* accessID, char* msgBuffer,unsigned int sizeOfMsg, unsigned int* logID); typedef __declspec(dllimport) struct tagCALLBACK_MESSAGE{ char caccessID[20]; char* cpmessage; int ilengthMsg; int irspCode; unsigned int ilogID; } CALLBACK_MESSAGE; C# [DllImport("GTPAPI.dll", CallingConvention = CallingConvention.Cdecl,EntryPoint = "GTPLogin",CharSet =CharSet.Ansi)] public static extern int GTPLogin(string ipList, string portList, string accessID, string accessPasswd, string certificatePath, string certificatePasswd,ref BREAK_DATA_INFO breakdata); [DllImport("GTPAPI.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "GTPMsgRec", CharSet = CharSet.Ansi)] public static extern int GTPMsgRec(string accessID,callBack pcallback,callErrorBack callerror); [DllImport("GTPAPI.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "GTPMsgSend",CharSet =CharSet.Ansi)] public static extern int GTPMsgSend(string accessID, StringBuilder msgBuffer, uint sizeOfMsg, ref uint logID); [StructLayout(LayoutKind.Sequential,CharSet =CharSet.Ansi,Pack =1)] public struct CALLBACK_MESSAGE { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string caccessID; [MarshalAs(UnmanagedType.LPStr)] public String cpmessage; [MarshalAs(UnmanagedType.U4)] public int ilengthMsg; [MarshalAs(UnmanagedType.U4)] public int irspCode; [MarshalAs(UnmanagedType.U4)] public uint ilogID; } 麻烦帮看一下,第一次写,不会,谢谢了
xian_wwq 2016-01-19
  • 打赏
  • 举报
回复
把dll的api定义和dllimport贴一下, 有助于分析问题

110,533

社区成员

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

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

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