我用C#调用C/C++的.dll文件,程序调试没有问题,但是点击open port与reset port就会出现以下错误:
open port:对 PInvoke 函数“usb key!usb_key.Form1::HD_OpenPort”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
reset port:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
open port 与reset port 函数原型如下:
unsigned short HD_OpenPort(
short ivPortNo,//usb端口编号:21,22,23,24
unsigned ivBaund,//通信波特率
short ivParity,//校验方式,0
HANDLE *devNo//返回设备号
)
unsigned short HD_ResetCard(
HANDLE devNo,//由HD_OpenPort返回的设备号
unsigned char *srATR,//存放收到的数据
short *srATRLen,//存放接受到的数据的长度
short ivCardSeat//卡座号,1
)我将代码贴在下面:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
namespace usb_key
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public const int WM_DEVICECHANGE = 0x219;
public const int DBT_DEVNODES_CHANGED = 0x0007;
System.IntPtr hHandle;
StringBuilder szATR = new StringBuilder("0", 32);
StringBuilder sData = new StringBuilder("0",180);
StringBuilder rData = new StringBuilder("0",320);
StringBuilder key = new StringBuilder("0",32);
StringBuilder data = new StringBuilder("0",180);
StringBuilder data2 = new StringBuilder("0",180);
StringBuilder data3 = new StringBuilder("0",180);
StringBuilder msg = new StringBuilder("0",180);
int flag;
System.UInt16 nATRLen, ReplyLen;
[DllImport("HDIFD20B.dll", CharSet = CharSet.Auto)]
public static extern System.UInt16 HD_OpenPort(System.Int16 portNum, System.UInt64 bland, System.Int16 parity, IntPtr hHandle);
[DllImport("HDIFD20B.dll", CharSet = CharSet.Auto)]
public static extern System.UInt16 HD_ResetCard(IntPtr hHandle, ref StringBuilder srATR, ref System.UInt16 srATRLen, System.Int16 ivCardseat);
//[DllImport("HDIFD20B.dll")]
//public static extern System.UInt16 HD_ProbeCard(IntPtr hHandle, System.UInt16 ivCardseat);
protected override void WndProc(ref Message m)
{
try
{
if (m.Msg == WM_DEVICECHANGE)
{
switch (m.WParam.ToInt32())
{
case WM_DEVICECHANGE:
break;
case DBT_DEVNODES_CHANGED:
MessageBox.Show("设备有变化");
break;
default:
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
base.WndProc(ref m);
} private void cboxAccessories_SelectedIndexChanged(object sender, EventArgs e)
{ }
private void btnchoose_Click(object sender, EventArgs e)
{
oFDialogSFile.InitialDirectory = "C:\\";
oFDialogSFile.Filter = "all file(*.*)|*.*";
oFDialogSFile.RestoreDirectory = true;
oFDialogSFile.ShowDialog();
cboxAccessories.Items.Add(oFDialogSFile.FileName.Trim());
cboxAccessories.Text = oFDialogSFile.FileName.Trim();
} private void btncancle_Click(object sender, EventArgs e)
{
if (cboxAccessories.Text == "")
{
MessageBox.Show("没有要取消的文件!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("确定要删除文件!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
cboxAccessories.Items.Remove(cboxAccessories.Text.Trim());
}
} private void btnopen_Click(object sender, EventArgs e)
{
int flag = HD_OpenPort(21, 0, 0, hHandle);//托管签名与非托管的目标签名不匹配(3)
if (flag != 0x9000)
{ MessageBox.Show("打开设备失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); }
else
{
MessageBox.Show("打开设备成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void btncheck_Click(object sender, EventArgs e)
{ // flag = HD_ProbeCard(hHandle, 1);
// while (flag == 0x9000)
// {
// MessageBox.Show("key已安装", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
// } }
private void btnreset_Click(object sender, EventArgs e)
{
int flag = HD_ResetCard(hHandle, ref szATR, ref nATRLen, 1);
while (flag == 0x9000)
{
MessageBox.Show("卡复位", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void btncode_Click(object sender, EventArgs e)
{
}
}
}
open port:对 PInvoke 函数“usb key!usb_key.Form1::HD_OpenPort”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
reset port:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
open port 与reset port 函数原型如下:
unsigned short HD_OpenPort(
short ivPortNo,//usb端口编号:21,22,23,24
unsigned ivBaund,//通信波特率
short ivParity,//校验方式,0
HANDLE *devNo//返回设备号
)
unsigned short HD_ResetCard(
HANDLE devNo,//由HD_OpenPort返回的设备号
unsigned char *srATR,//存放收到的数据
short *srATRLen,//存放接受到的数据的长度
short ivCardSeat//卡座号,1
)我将代码贴在下面:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
namespace usb_key
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public const int WM_DEVICECHANGE = 0x219;
public const int DBT_DEVNODES_CHANGED = 0x0007;
System.IntPtr hHandle;
StringBuilder szATR = new StringBuilder("0", 32);
StringBuilder sData = new StringBuilder("0",180);
StringBuilder rData = new StringBuilder("0",320);
StringBuilder key = new StringBuilder("0",32);
StringBuilder data = new StringBuilder("0",180);
StringBuilder data2 = new StringBuilder("0",180);
StringBuilder data3 = new StringBuilder("0",180);
StringBuilder msg = new StringBuilder("0",180);
int flag;
System.UInt16 nATRLen, ReplyLen;
[DllImport("HDIFD20B.dll", CharSet = CharSet.Auto)]
public static extern System.UInt16 HD_OpenPort(System.Int16 portNum, System.UInt64 bland, System.Int16 parity, IntPtr hHandle);
[DllImport("HDIFD20B.dll", CharSet = CharSet.Auto)]
public static extern System.UInt16 HD_ResetCard(IntPtr hHandle, ref StringBuilder srATR, ref System.UInt16 srATRLen, System.Int16 ivCardseat);
//[DllImport("HDIFD20B.dll")]
//public static extern System.UInt16 HD_ProbeCard(IntPtr hHandle, System.UInt16 ivCardseat);
protected override void WndProc(ref Message m)
{
try
{
if (m.Msg == WM_DEVICECHANGE)
{
switch (m.WParam.ToInt32())
{
case WM_DEVICECHANGE:
break;
case DBT_DEVNODES_CHANGED:
MessageBox.Show("设备有变化");
break;
default:
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
base.WndProc(ref m);
} private void cboxAccessories_SelectedIndexChanged(object sender, EventArgs e)
{ }
private void btnchoose_Click(object sender, EventArgs e)
{
oFDialogSFile.InitialDirectory = "C:\\";
oFDialogSFile.Filter = "all file(*.*)|*.*";
oFDialogSFile.RestoreDirectory = true;
oFDialogSFile.ShowDialog();
cboxAccessories.Items.Add(oFDialogSFile.FileName.Trim());
cboxAccessories.Text = oFDialogSFile.FileName.Trim();
} private void btncancle_Click(object sender, EventArgs e)
{
if (cboxAccessories.Text == "")
{
MessageBox.Show("没有要取消的文件!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("确定要删除文件!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
cboxAccessories.Items.Remove(cboxAccessories.Text.Trim());
}
} private void btnopen_Click(object sender, EventArgs e)
{
int flag = HD_OpenPort(21, 0, 0, hHandle);//托管签名与非托管的目标签名不匹配(3)
if (flag != 0x9000)
{ MessageBox.Show("打开设备失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); }
else
{
MessageBox.Show("打开设备成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void btncheck_Click(object sender, EventArgs e)
{ // flag = HD_ProbeCard(hHandle, 1);
// while (flag == 0x9000)
// {
// MessageBox.Show("key已安装", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
// } }
private void btnreset_Click(object sender, EventArgs e)
{
int flag = HD_ResetCard(hHandle, ref szATR, ref nATRLen, 1);
while (flag == 0x9000)
{
MessageBox.Show("卡复位", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void btncode_Click(object sender, EventArgs e)
{
}
}
}
解决方案 »
- 论坛发贴机原理是什么呀?
- 构造函数为什么要和类同名?
- 有没有人知道为什么这个readyState始终是loading啊?mshtml相关
- 在FORM窗口中调用API创建子窗口,却总是显示不出来,这是为什么
- 如何让项目能兼容多种数据库,而不管我写的sql是哪种?即如何写一个sql parse?up有分!
- 如何将剪贴板内的 连接地址(如www.baidu.com)添加超链接 粘贴在RichTextBox
- 如何判断系统是否有声卡?
- 在web开发中,如果做到这样一个小功能?--
- SQL SERVER中的数据类型都有哪些,在C#中对应的都是什么?
- c#窗体浏览本地文件夹找到需要的几个文件夹并显示在文本框内
- [winform]如何比对本地文件与服务器文件不同
- 串口数据处理
public static extern System.UInt16 HD_OpenPort(System.Int16 portNum, System.UInt64 bland, System.Int16 parity, ref IntPtr hHandle); 加个ref 实验下.
public static extern System.UInt16 HD_OpenPort(System.Int16 portNum, System.UInt64 bland, System.Int16 parity, IntPtr hHandle); 第二个参数是64位的吗?
unsigned short HD_ResetCard(
HANDLE devNo,//由HD_OpenPort返回的设备号
unsigned char *srATR,//存放收到的数据
short *srATRLen,//存放接受到的数据的长度
short ivCardSeat//卡座号,1
)
各位高手,麻烦帮我看看这个函数的C#声明与调用怎么写呀!
如果是,C#中怎样得到它指向的值?
[DllImport("HDIFD20B.dll", CharSet = CharSet.Auto)]
public static extern System.UInt16 HD_ResetCard(IntPtr hHandle, ref IntPtr hHandle2, ref System.UInt16 srATRLen, System.Int16 ivCardseat);
________________unsigned char *srATR,//存放收到的数据
short *srATRLen,//存放接受到的数据的长度
___________
用Marshal.Copy (Char[], Int32, IntPtr, Int32) 把数据从非托管环境拷贝到托管内存下,就随便你操作了.如果不行 Marshal 类,你去msdn上看看,帮助的方法非常的多.
我用了marshal.copy,结果出现下面错误:运行库遇到了错误。此错误的地址为 0x79e78a2a,在线程 0x97c 上。错误代码为 0xc0000005。此错误可能是 CLR 中的 bug,或者是用户代码的不安全部分或不可验证部分中的 bug。此 bug 的常见来源包括用户对 COM-interop 或 PInvoke 的封送处理错误,这些错误可能会损坏堆栈。
代码如下:
Byte[] szATR = new Byte[32];
[DllImport("HDIFD20B.dll", CharSet = CharSet.Auto)]
public static extern System.UInt16 HD_ResetCard( IntPtr hHandle, ref Byte[] hHandle1, ref IntPtr nATRLen, System.UInt16 ivCardseat);
private void btnreset_Click(object sender, EventArgs e)
{
Marshal.Copy(hHandle1, szATR, 0, 32);
flag = HD_ResetCard( hHandle, ref szATR,ref nATRLen, 1);
while(flag == 0x9000)
{
MessageBox.Show("卡复位", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
short ivPortNo,//usb端口编号:21,22,23,24
unsigned ivBaund,//通信波特率
short ivParity,//校验方式,0
HANDLE *devNo//返回设备号
)
devNo是HANDLE指针,也就是 void**unsigned short HD_ResetCard(
HANDLE devNo,//由HD_OpenPort返回的设备号
unsigned char *srATR,//存放收到的数据
short *srATRLen,//存放接受到的数据的长度
short ivCardSeat//卡座号,1
)
devNo是HANDLE,是void*
HANDLE devNo,//由HD_OpenPort返回的设备号
unsigned char *srATR,//存放收到的数据
short *srATRLen,//存放接受到的数据的长度
short ivCardSeat//卡座号,1
) __________________________________[DllImport("HDIFD20B.dll", CharSet = CharSet.Auto)]
public static extern System.UInt16 HD_ResetCard( IntPtr hHandle, ref Byte[] hHandle1, ref IntPtr nATRLen, System.UInt16 ivCardseat);
________________________Marshal.Copy (IntPtr, Int16[], Int32, Int32)
参数
source
内存指针,从中进行复制。 destination
要复制到的数组。 startIndex
数组中 Copy 开始位置的从零开始的索引。 length
要复制的数组元素的数目。
写成
[DllImport("HDIFD20B.dll", CharSet = CharSet.Auto)]
public static extern System.UInt16 HD_ResetCard(IntPtr hHandle, ref IntPtr hHandle2, ref System.UInt16 srATRLen, System.Int16 ivCardseat);
..............
HD_ResetCard(p1 , p2 , len, strlen);byte[] buffers = new byte[len];
Marshal.Copy(p2 , buffers , 0 , len);你看行不行.