c# 获取串口设备的输入(unsigned char *和 char*)

本文介绍了如何在C#中调用DLL文件,重点讲解了类型转换、指针操作及安全代码使用等内容,通过示例展示了如何实现密码键盘的密码输入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为是C#,所以平台肯定是.NET了。

之前因为一个小小的业务需要接触了下密码键盘的操作。其实就是简单的获取用户输入密码的操作,没碰到什么大的问题,但是查资料的过程中还是感觉查到的东西挺多的,是那种越查越多,但是又不是很关键的东西。

在调用DLL中的方法的时候,我们一般要对照函数说明来把C/C++中的类型转换为.NET中相对应的类型,而且方法必须声明为静态外部函数,即加上public  extern static声明头.如果不加public ,函数默认为私有函数,调用就会出错。

[DllImport("COM DLL path/file")]
public extern static int FunctionName(byte param1, ushort param2)

 

类型对照表:

Win32 Types
CLR Type
char, INT8, SBYTE, CHAR 
System.SByte
short, short int, INT16, SHORT
System.Int16
int, long, long int, INT32, LONG32, BOOL , INT
System.Int32
__int64, INT64, LONGLONG
System.Int64
unsigned char, UINT8, UCHAR , BYTE
System.Byte
unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR , __wchar_t
System.UInt16
unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT
System.UInt32
unsigned __int64, UINT64, DWORDLONG, ULONGLONG
System.UInt64
float, FLOAT
System.Single
double, long double, DOUBLE
System.Double
 对于普通的函数调用一般类型对应上就没什么问题了,但是对于涉及到指针操作和回调操作的就会复杂一些,当然熟悉了也就不复杂了,这里只涉及指针的操作。
如果DLL中有一个函数的传人参数是一个指针的话,如:
int __stdcall FunctionName(unsigned char *param2)这就当是DLL的一个函数说明,返回值是INT,传入参数是一个指针,类型是unsigned char。对于CHAR和STRING类型的区别本来找到个说的比较好的文章,但是回到家里后就找不到那文章了。他们的区别就是字符和字符串的区别,char 声明并赋值的时候只能是单字符的,char c = 'c';而string声明和赋值的时候可以是单字符也可以是很多个单字符连在一起组成一个串,string s = "cc";C/C++在表示字符串的时候是以字符数组来表示的,char[] c;
在调用包括指针操作的函数的时候,除了对照类型,我们还得考虑采用的处理方式。 “对于这种情况可以使用C#提供的非安全代码来进行解决,但是,毕竟是非托管代码,垃圾资源处理不好的话对应用程序是很不利的。所以还是使用C#提供的ref以及out修饰字比较好。”
非安全代码是.NET为了指针操作的需要而特别设置的功能,所以既然是针对指针而留的,那应该也是最合适的处理方法了。后面试了下ref的方式,提示实例的异常,也许是指针传的不对,找不到对象了。

使用:已密码键盘获取密码输入为例

函数说明:int __stdcall inputpassword(unsigned char *param)

.NET中使用:

声明:

[DllImport("COM DLL path/file")]
unsafe public static extern int inputpassword(byte* param);这里我们用BYTE对应char*

调用:放在哪里自己决定

byte[]  password = new byte[6];\\密码键盘输入为6位,所以长度设为6就可以了

unsafe

{

   //fixed的MSDNhttp://msdn.microsoft.com/zh-cn/library/f58wzh21(VS.80).aspx

    fixed(byte* array=password ) //这里获取的是password 的地址,并FIX,就是固定“fixed 语句禁止垃圾回收器重定位可移动的变量”

    {

        int ret_value = inputpassword(array);//这里传入的是指针,因为unsigned char *param就是一个指针。

    }

}

语句执行后的结果是输入的密码会保存在password 字节数组中,之后就是调用相应的方法把password 转换成6位密码字符了。

 

转载于:https://www.cnblogs.com/ruanbl/archive/2009/05/31/1493252.html

#include <reg51.h> #include <intrins.h> // 硬件引脚定义 sbit DS18B20 = P3^7; // 温度传感器数据线 sbit BEEP = P1^0; // 蜂鸣器控制 sbit LED = P1^1; // 报警LED sbit MOTOR = P1^2; // 直流电机控制 sbit IR = P3^2; // 红外接收器 (INT0) // LCD1602控制引脚 sbit RS = P2^0; sbit RW = P2^1; sbit EN = P2^2; #define LCD_PORT P0 // LCD数据端口 // 全局变量 unsigned char flag_armed = 0; // 设防状态 (0:撤防, 1:设防) unsigned char current_temp = 0; // 当前温度值 unsigned char alarm_temp = 40; // 报警温度阈值(默认40℃) // 函数声明 void DS18B20_Init(); unsigned char DS18B20_ReadByte(); void DS18B20_WriteByte(unsigned char dat); unsigned int DS18B20_GetTemp(); void LCD_Init(); void LCD_Cmd(unsigned char cmd); void LCD_Data(unsigned char dat); void LCD_DisplayTemp(unsigned char temp); void LCD_DisplayState(); void UART_Init(); void UART_SendString(char *str); void Delayms(unsigned int ms); void BeepAlarm(unsigned char t); void MotorControl(unsigned char state); void IR_Init(); void IR_Decode(); /*********************** 主函数 ***********************/ void main() { unsigned int temp_val; // 初始化 DS18B20_Init(); LCD_Init(); UART_Init(); IR_Init(); // 显示初始信息 LCD_Cmd(0x80); // 第一行 LCD_Data('T'); LCD_Data('e'); LCD_Data('m'); LCD_Data('p'); LCD_Data(':'); LCD_Data(' '); LCD_Data(alarm_temp/10 + '0'); LCD_Data(alarm_temp%10 + '0'); LCD_Data(0xDF); // 度符号 LCD_Data('C'); LCD_Cmd(0xC0); // 第二行 LCD_Data('S'); LCD_Data('t'); LCD_Data('a'); LCD_Data('t'); LCD_Data('e'); LCD_Data(':'); LCD_Data('O'); LCD_Data('F'); LCD_Data('F'); // 初始状态 MotorControl(0); // 关闭电机 LED = 1; // 关闭LED BEEP = 1; // 关闭蜂鸣器 while(1) { // 读取温度 temp_val = DS18B20_GetTemp(); current_temp = temp_val >> 4; // 取整数部分 // LCD显示当前温度 LCD_DisplayTemp(current_temp); // 设防状态检测 if(flag_armed && (current_temp > alarm_temp)) { LED = 0; // 点亮报警LED MotorControl(1); // 启动电机 BeepAlarm(1); // 蜂鸣器报警 UART_SendString("fire!\r\n"); // 串口发送报警信息 } else { LED = 1; // 关闭LED MotorControl(0); // 关闭电机 BEEP = 1; // 关闭蜂鸣器 } // 处理红外解码 IR_Decode(); Delayms(200); // 延时200ms } } /*********************** 红外遥控处理 ***********************/ void IR_Init() { IT0 = 1; // 设置INT0为下降沿触发 EX0 = 1; // 使能INT0中断 EA = 1; // 开总中断 } void IR_Decode() interrupt 0 { unsigned char i, j; unsigned char byte = 0; unsigned char ir_code[4]; // 存储解码结果 // 等待9ms引导脉冲 Delayms(1); if(IR) return; // 干扰信号 // 检查4.5ms高电平 Delayms(4); if(!IR) return; // 解码32位数据 for(i=0; i<4; i++) { for(j=0; j<8; j++) { while(!IR); // 等待高电平 Delayms(0); if(IR) { byte = (byte >> 1) | 0x80; // 收到1 while(IR); // 等待低电平 } else { byte >>= 1; // 收到0 } } ir_code[i] = byte; } // 按键1: 设防 if(ir_code[2] == 0x0C) { flag_armed = 1; LCD_DisplayState(); BeepAlarm(0); // 短提示音 } // 按键2: 撤防 else if(ir_code[2] == 0x18) { flag_armed = 0; LCD_DisplayState(); BeepAlarm(0); // 短提示音 } EX0 = 1; // 重新使能中断 } /*********************** 电机控制 ***********************/ void MotorControl(unsigned char state) { if(state) { MOTOR = 1; // 启动电机 } else { MOTOR = 0; // 停止电机 } } /*********************** DS18B20温度传感器 ***********************/ void DS18B20_Init() { unsigned char i; DS18B20 = 1; while(i--); DS18B20 = 0; i = 227; while(--i); // 延时480us DS18B20 = 1; i = 29; while(--i); // 延时60us } unsigned char DS18B20_ReadByte() { unsigned char i, j, dat = 0; for(i=0; i<8; i++) { DS18B20 = 0; _nop_(); dat >>= 1; DS18B20 = 1; _nop_(); if(DS18B20) dat |= 0x80; j = 29; while(--j); // 延时60us } return dat; } void DS18B20_WriteByte(unsigned char dat) { unsigned char i, j; for(i=0; i<8; i++) { DS18B20 = 0; _nop_(); DS18B20 = dat & 0x01; j = 29; while(--j); // 延时60us DS18B20 = 1; dat >>= 1; } } unsigned int DS18B20_GetTemp() { unsigned char tempL, tempH; unsigned int temp; DS18B20_Init(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x44); // 启动温度转换 Delayms(750); // 等待转换完成 DS18B20_Init(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0xBE); // 读取温度 tempL = DS18B20_ReadByte(); tempH = DS18B20_ReadByte(); temp = (tempH << 8) | tempL; return temp; } /*********************** LCD1602显示 ***********************/ void LCD_Init() { Delayms(15); LCD_Cmd(0x38); // 8位模式,2行显示,5x8点阵 LCD_Cmd(0x0C); // 开显示,关光标 LCD_Cmd(0x06); // 写入后光标右移 LCD_Cmd(0x01); // 清屏 } void LCD_Cmd(unsigned char cmd) { RS = 0; RW = 0; EN = 0; LCD_PORT = cmd; EN = 1; Delayms(1); EN = 0; } void LCD_Data(unsigned char dat) { RS = 1; RW = 0; EN = 0; LCD_PORT = dat; EN = 1; Delayms(1); EN = 0; } void LCD_DisplayTemp(unsigned char temp) { LCD_Cmd(0x85); // 第一行第5列 LCD_Data(temp/10 + '0'); // 十位 LCD_Data(temp%10 + '0'); // 个位 LCD_Data(0xDF); // 度符号 LCD_Data('C'); } void LCD_DisplayState() { LCD_Cmd(0xC6); // 第二行第6列 if(flag_armed) { LCD_Data('O'); LCD_Data('N'); LCD_Data(' '); } else { LCD_Data('O'); LCD_Data('F'); LCD_Data('F'); } } /*********************** 串口通信 ***********************/ void UART_Init() { TMOD = 0x20; // 定时器1模式2 TH1 = 0xFD; // 9600波特率 (11.0592MHz) TL1 = 0xFD; TR1 = 1; // 启动定时器1 SCON = 0x50; // 串口模式1, 允许接收 } void UART_SendString(char *str) { while(*str) { SBUF = *str++; while(!TI); TI = 0; } } /*********************** 辅助函数 ***********************/ void BeepAlarm(unsigned char t) { unsigned char i; if(t) { // 长报警 for(i=0; i<100; i++) { BEEP = ~BEEP; Delayms(5); } BEEP = 1; } else { // 短提示音 for(i=0; i<20; i++) { BEEP = ~BEEP; Delayms(2); } BEEP = 1; } } void Delayms(unsigned int ms) { unsigned int i, j; for(i=0; i<ms; i++) for(j=0; j<114; j++); }
最新发布
06-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值