求c#中引用非托管代码的DLL库的方法报错的解决办法

skykevin 2006-05-09 11:20:59
...全文
1490 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
yinweihong 2006-05-10
  • 打赏
  • 举报
回复
调用导致堆栈不对称---是指你的传参调用约定
托管的 PInvoke 签名与非托管的目标签名不匹配---是指你的参数传递方式(传值还是传引用)


参考我的回复先,在VB6,VB.NET里面我一直是那么做的,包括DLL中FUNCTION的EXPORTS和API DECLARE等
skykevin 2006-05-10
  • 打赏
  • 举报
回复
如下封装另一个方法,调用时报同样的错。用c#如何取到主叫号码?

一、封闭:
//int TV_ReceiveCallingID (int , char far *,int);
//功能: 取出主叫号码
//参数: 通道号
// 存放主叫号码的字符串指针
// 字符串长度
//返回: 接收的字符数
//说明: 接收主叫号可在振铃之前或第一声振铃之后,由电信局设置。而且必须在交换局申请此功能。
[DllImport("usbid.dll", CharSet = CharSet.Ansi)]
public static extern int TV_ReceiveCallingID(int i, [MarshalAs(UnmanagedType.LPStr)] ref StringBuilder sTel, int iLenght);
public static int ReceiveCallingID(int i, ref StringBuilder sTel, int iLenght)
{
return TV_ReceiveCallingID(i, ref sTel, iLenght);
}
二、调用:
StringBuilder sTel=new StringBuilder(20);
UsbTel.ReceiveCallingID(iChannel, ref sTel, 24);//捕捉主叫号码

运行报错:
对 PInvoke 函数“zx_voice!zx_voice.UsbTel::TV_ReceiveCallingID”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
Knight94 2006-05-10
  • 打赏
  • 举报
回复
你把dllimport中的charset属性去掉再试试,例如:
[DllImport("usbid.dll")]
Knight94 2006-05-10
  • 打赏
  • 举报
回复
你的调用应该没有什么问题,很怪
skykevin 2006-05-10
  • 打赏
  • 举报
回复
to Knight94(愚翁):
按所说方法又试了下,加out,还是取不到sTel的值。我是如此调用的:

StringBuilder sTel=new StringBuilder(256);
iRtn=UsbTel.ReceiveCallingID(iChannel, sTel, sTel.Capacity);
Knight94 2006-05-10
  • 打赏
  • 举报
回复
不过你要给sTel分配空间的时候,要注意能放的下数据。
Knight94 2006-05-10
  • 打赏
  • 举报
回复
or

[DllImport("usbid.dll", CharSet = CharSet.Ansi)]
public static extern int TV_ReceiveCallingID(int i, [Out] StringBuilder sTel, int iLenght);

//Calling
StringBuilder sTel = new StringBuilder( 30 );
TV_ReceiveCallingID( iChannel, sTel, 30);
Knight94 2006-05-10
  • 打赏
  • 举报
回复
have a try!

[DllImport("usbid.dll", CharSet = CharSet.Ansi)]
public static extern int TV_ReceiveCallingID(int i, StringBuilder sTel, int iLenght);

//Calling
StringBuilder sTel = new StringBuilder( 30 );
TV_ReceiveCallingID( iChannel, sTel, 30);
skykevin 2006-05-10
  • 打赏
  • 举报
回复
to Knight94(愚翁):
按所说方法,编译运行不会报错,但取sTel值为空。因为dll中的方法是把主叫号存在sTel中的。我试过如果在sTel前加ref或out,运行会报错,该如何处理?
Knight94 2006-05-10
  • 打赏
  • 举报
回复
如果是char*的话,如下就可以了

[DllImport("usbid.dll", CharSet = CharSet.Ansi)]
public static extern int TV_ReceiveCallingID(int i, StringBuilder sTel, int iLenght);
skykevin 2006-05-10
  • 打赏
  • 举报
回复
楼上的针对问题能不能说具体点。
zhaoliang_chen 2006-05-09
  • 打赏
  • 举报
回复
dll需要符合标准
Knight94 2006-05-09
  • 打赏
  • 举报
回复
to 用c#中引用非托管代码的DLL库的方法:
long TV_StartPlayFile (int, char *, long, long)

是标准的dll吗,你是否用dllimport引入
yinweihong 2006-05-09
  • 打赏
  • 举报
回复
C++的默认参数约定是CDECL的,在原型前面加个_STDCALL,再编译,DEF文件做的EXPORTS?

C#中的string前面加个ref试试
活靶子哥哥 2006-05-09
  • 打赏
  • 举报
回复
http://www.aspxboy.com/private/showthread.asp?threadid=369
http://www.aspxboy.com/private/showthread.asp?threadid=370
skykevin 2006-05-09
  • 打赏
  • 举报
回复
我是如下写的,
public static long StartPlayFile(int i, string sFile, long lStart, long lLength)
{
return TV_StartPlayFile( i, sFile, lStart, lLength);
}
skykevin 2006-05-09
  • 打赏
  • 举报
回复
用c#中引用非托管代码的DLL库的方法:
long TV_StartPlayFile (int, char *, long, long)
skykevin 2006-05-09
  • 打赏
  • 举报
回复
论坛的不良信息过滤好象有问题:一有方法名就报:请不要发表可能给我们带来伤害的言论,谢谢配合
Knight94 2006-05-09
  • 打赏
  • 举报
回复
如何声明的,以及如何调用的。
最好把dll原型声明也贴出来。
diandian82 2006-05-09
  • 打赏
  • 举报
回复
mark
加载更多回复(7)
Kite Report是市场上最灵活的.Net报表引擎. l 他是一套100%托管的.Net组件. l 支持高度复杂报表包含分组,多列,交叉,两次报表, C#/VB.NET脚本等. l 提供最终用户报表设计功能.可在预览时对生成的报表进行修改后再打印. l 方便强大的可视化设计工具。您通过简单的托拽和设置就可以制作普通的报表。 l 报表采用C#在.Net 2.0 上开发。 l 报表的数据源可以使用所有的.Net数据类型,如DataSet, DataTable, ArrayList,自定义实体类等,方便和您的程序进行集成。 l 集成图片,条码等报表常用控件。 l 强大的脚本功能。脚本支持C#/VB.Net语言。有编译报错机制。通过脚本可以极大的提供报表应用的灵活性。 l 结构开放灵活方便您和您的框架程序集成。例如提供自定义预览窗口。 l 文英文两种语言支持(使用可扩展的多语言支持技术)。 l 在报表可以通过脚本直接与应用程序交互. 产品特性: 兼容: · 托管的报表引擎 · 设计器支持设计时和运行时 · 支持WinForms和WebForms · 支持所有.Net数据源类型,包括DataSets,DataViews,Collections,Arrays和类实现IEnumerable, IList or IListSource,一张报表支持多个数据源 · 使用GDI+实现:渐变填充,透明度,定制形状等 · 支持C#/VB.NET脚本,也支持其他.NET平台的其他语言,使用者不需要学习新的语言 灵活: · 在一个报表可以实现无限主从报表 · 生成交叉报表是容易的 · 脚本拥有完全控制权,包含项目的名字空间,变量,方法等 · 报表控件容易学习和使用 · 支持各种报表尺寸和不同打印方向 · 灵活的报表页头/页脚使你的报表好看且容易理解 · 强大的Page Overlays允许你打印漂亮的报表背景,例如水印 · 开放的插件架构,支持扩充自己的报表控件 · 丰富的报表控件,包含文本,形状,图片,条形码,邮编.同样能使用WinForms的控件作为报表元素 · 报表样式支持,你可以使用不同的样式来优化报表针对预览,打印和导出等 · 支持约束和约束模式 · 米制和英寸度量单位 · 加大的数据绑定模式(类似于Win/Web Forms的数据绑定)允许你绑定数据源,系统和本地变量到所有控件属性,也可以使用脚本表达式(C#/VB.NET) · 支持导出到PDF, HTML, RTF, EMF, BMP, JPG, GIF, PNG, TIFF, Excel, CSV and Text文件 容易使用和发布 · 容易发布,核心公两个DLL · 报表文件是XML格式,方便共享

110,566

社区成员

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

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

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