现在有个硬件的DLL,我们需要通过DLL控制硬件设备,需要用到DLL的2个函数,这2个函数原型是这样的JS_OK 对应值 1,
JS_COMM_ERR 对应值-3,
JS_TYPE_ERR对应值-10。HANDLE PASCAL OpenCommPort(LPCSTR lpszPortNum,DWORD dwBaudRate)
lpszPortNum 为串行端口,dwBaudRate为端口通讯速率。函数正确运行返回端口句柄。LONG PASCAL OpenDoor(HANDLE hCom,BYTE Devno,BYTE CtrNo)
hCom为端口句柄,Devno 设备号,CtrNo为控制类型,默认0。函数调用成功返回JS_OK,不成功返回JS_COMM_ERR或者JS_TYPE_ERR。我不熟悉PASCAL,关于数据类型的对应声明估计出现了问题,我在C#中这样调用
[DllImport(@"D:\招投标中心项目\201Comm.dll", EntryPoint = "OpenCommPort", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]public static extern long OpenCommPort(string num, int intBaudRate);[DllImport(@"D:\招投标中心项目\201Comm.dll", EntryPoint = "OpenDoor", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]public static extern int OpenDoor(ref long Handle,int Devno, int CtrNo);程序中调用的地方这样调用
long a = OpenCommPort("COM1", 9600);
int b = OpenDoor(ref a,0, 1);
现在测试a值可以正确返回端口句柄号
b的值总是-3,不知道是否是参数类型设置错误,请大家帮忙看下。
JS_COMM_ERR 对应值-3,
JS_TYPE_ERR对应值-10。HANDLE PASCAL OpenCommPort(LPCSTR lpszPortNum,DWORD dwBaudRate)
lpszPortNum 为串行端口,dwBaudRate为端口通讯速率。函数正确运行返回端口句柄。LONG PASCAL OpenDoor(HANDLE hCom,BYTE Devno,BYTE CtrNo)
hCom为端口句柄,Devno 设备号,CtrNo为控制类型,默认0。函数调用成功返回JS_OK,不成功返回JS_COMM_ERR或者JS_TYPE_ERR。我不熟悉PASCAL,关于数据类型的对应声明估计出现了问题,我在C#中这样调用
[DllImport(@"D:\招投标中心项目\201Comm.dll", EntryPoint = "OpenCommPort", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]public static extern long OpenCommPort(string num, int intBaudRate);[DllImport(@"D:\招投标中心项目\201Comm.dll", EntryPoint = "OpenDoor", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]public static extern int OpenDoor(ref long Handle,int Devno, int CtrNo);程序中调用的地方这样调用
long a = OpenCommPort("COM1", 9600);
int b = OpenDoor(ref a,0, 1);
现在测试a值可以正确返回端口句柄号
b的值总是-3,不知道是否是参数类型设置错误,请大家帮忙看下。
public static extern int OpenDoor(IntPtr Handle,byte Devno, byte CtrNo);
public static extern IntPtr OpenCommPort([InAttribute()] [MarshalAsAttribute(UnmanagedType.LPStr)] string lpszPortNum, uint dwBaudRate) ;
[DllImportAttribute(@"D:\招投标中心项目\201Comm.dll", EntryPoint="OpenDoor", CallingConvention=CallingConvention.StdCall)]
public static extern int OpenDoor(IntPtr hCom, byte Devno, byte CtrNo) ;
试下吧,不知道好不好.
非常感谢,请问能解释下这个的意思么, [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPStr)]
同时LPDWORD又应该对应什么的类型呢?
LPDWORD [InAttribute(),OutAttribute()]ref uint LPDWORD
这个估计得视情况而看吧.
指示应将数据从调用方封送到被调用方,而不返回到调用方。
InAttribute 是可选项。只有 COM Interop 和平台调用才支持此属性。如果缺少显式设置,Interop 封送拆收器将根据参数类型来假定规则,不论参数是通过引用传递还是通过值传递,也不论类型是可直接复制到本机结构中,还是不能直接复制到本机结构中。例如,始终假定 StringBuilder 类为 In/Out,并假定通过值传递的字符串数组为 In。LPDWORD,为DWORD指针,C#可以使用ref uint试试
函数原型如下
LONG PASCAL AddList(HANDLE hCom,BYTE DevNo,DWORD CardSN,LPCSTR pName,LPCSTR pNo,LPCSTR pPIN,LPCSTR pLimitTime,BYTE Door1App,BYTE Door2App)数据取值说明
pName持卡人姓名字符串超过8 个字符(4 个汉字),之后的将被截除,
pNo 持卡人工号字符串超过11 个字符,之后的将被截除,
pPIN 持卡人个人密码最多6 位数字(0——9),
组成pLimitTime 卡片有效期字符串格式如下:
年(2)+月(2)+日(2),十六进制表示
如:“030911”表示2003 年9 月17 日
Door1App 门1 的应用群组号有效取值范围(0——15)其余值均无效;可以用写入无效值,禁止卡片在此扇门的权限。
Door2App 门2 的应用群组号,同上我申明的语句:
[DllImport(@"D:\招投标中心项目\a08.dll", EntryPoint = "OpenCommPort", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]public static extern IntPtr OpenCommPort([InAttribute()] [MarshalAsAttribute(UnmanagedType.LPStr)] string lpszPortNum, uint dwBaudRate);[DllImport(@"D:\招投标中心项目\a08.dll", EntryPoint = "AddList", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]public static extern int AddList(IntPtr Handle, byte Devno, uint CardSn, string strName, string strNo, string strPass, string strLimitTime, byte Door1App, byte Door2App);
测试调用的时候
IntPtr a = OpenCommPort("COM1", 9600);
int b = AddList(a, 0, 9637114, "aaa", "000009", "222222", "030901", 0, 0);
执行后b的值总是返回说输入字符串长度不匹配,排除函数说明本身的错误外,请帮我坚持下是否函数申明和调用的哪个地方有问题呢?谢谢了!
现在还有个问题,就是对于像这样有输出参数的在C#中怎么申明
LONG PASCAL ReadCardSN(HANDLE hCom,BYTE Dno,LPDWORD pCardSn)
会在其中写上卡号什么的吧,用ref uint试试
public static extern int ReadCardSN(IntPtr Handle, byte Devno, [InAttribute(), OutAttribute()] ref uint CardSn);
同时还想请教一下,我自己的程序如何知道有人在读卡器上刷卡了呢,就是如何类似银行卡卡插进去后程序就会知道,并且做出处理。
public static extern int ReadCardSN(IntPtr Handle, byte Devno, [InAttribute(), OutAttribute()] ref uint CardSn);
卖硬件的厂商应该提供一个事件的,或者回调函数啥的
在厂商给的Dll中找找有没有CallBack字样的东西
参数是否正确,楼主完全可以用VC写一个Dll测试一下,我都不知道这样试过多少回了,好多麻烦的修饰[InAttribute(), OutAttribute()]之类的根本不需要
__declspec(dllexport) void ReadCard(LPDWORD pd)
{
DWORD dw = 345;
memcpy(pd, &dw, sizeof(DWORD));
}弄个.Net的控制台程序测试:class Program
{
[DllImport("Card.dll")]//导入Dll中的函数
static extern void ReadCard(ref uint dw); static void Main(string[] args)
{
uint dw = 0;
ReadCard(ref dw);
Console.WriteLine(dw);//输出345,调用正确
}
}猜一下:
LONG ReadCardSN(HANDLE hCom,BYTE Devno,LPDWORD pCardSn)
第二个参数应该是设备号
第三个参数应该是卡号,一个无符号32位整数的指针,读取的卡号要写到它指向的对象
应该看下DEMO中ReadCardSN是如何调用的,对于pCardSn参数是如何处理的
我好像遇到了 和你同一个 门禁的接口 调用问题
我手里的 DLL版本是delphi的 ,
不过 我没有相关的demo,
该死的提供商 理直气壮的向我吼道:“现在盗版那么多,我们怎么会提供二次开发文档,你说的那个是7,8年前的事情了”
楼主大人要是看到的话 ,能发下demo给我看看么? 我的email是 [email protected]