[转]PChar和Array [0..255] of Char的区别

本文探讨了在使用PChar类型变量从对话框编辑框中读取文本内容时遇到的问题及解决方案。当直接使用未分配内存的PChar类型变量时,GetDlgItemText函数无法正确读取内容。文章提供了两种解决方法:一是使用array[0..255]ofChar类型;二是为PChar类型变量分配足够的内存。

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

最近又犯了一个曾经犯过的错误,在编写一个纯API注册机的时候,问题来了。function DialogFunc(hwndDlg: HWND; msg: UINT; wParam: wParam; lParam: lParam): Boolean; stdcall;
var
    Name, Email: PChar;   //注意这里定义Name和Email为PChar类型
    Code: string;
begin
    case msg of
        WM_INITDIALOG:
            begin
                InitializeApp(hwndDlg, wParam, lParam);
                Result := True;
                Exit;
            end;
        WM_COMMAND:
            begin
                case (LOWORD(wParam)) of
                    IDB_GENERATE:
                        begin       
                            GetDlgItemText(hwndDlg, IDE_NAME, Name, 255); //注意尝试读取Name编辑框的内容
                            GetDlgItemText(hwndDlg, IDE_MAIL, Email, 255);//注意尝试读取Email编辑框的内容
                            //以上两者读取的结果都是空。尽管在资源文件里已经为这两个编辑框初始化了内容。
                            Code := GetSn(Name, Email);
                            SetDlgItemText(hwndDlg, IDE_CODE, PChar(Code));
                            Result := True;
                            Exit;
                        end;
                    IDB_EXIT:
                        begin
                            EndDialog(hwndDlg, 1);
                            Result := True;
                            Exit;
                        end;
                end;
                Result := False;
                Exit;
            end;
        WM_CLOSE:
            begin
                EndDialog(hwndDlg, 0);
                Result := True;
                Exit;
            end;
    end;
    Result := False;
end;

问题所在,看注释:

GetDlgItemText(hwndDlg, IDE_NAME, Name, 255); //注意尝试读取Name编辑框的内容
GetDlgItemText(hwndDlg, IDE_MAIL, Email, 255);//注意尝试读取Email编辑框的内容
//以上两者读取的结果都是空。尽管在资源文件里已经为这两个编辑框初始化了内容。

但如果把Name和Email的类型定义成 Name:array [0..255] of Char; 类型时,能成功读出编辑框里的内容。

郁闷了一段时间,后来才恍然大悟,原来array[0..255] of Char类型在声明的时候已经为变量分配了内存,而PChar类型只是一个空指针,没有分配内存,因此,尽管GetDlgItemText函数执行成功,但无法把读取到的内容保存到Name或Email内存空间里。

解决办法,除了用上述 array [0..255] of Char 方式定义,如果用PChar,就必须先分配内存,如:

Name, Email:PChar;

SetLength(Name,255);

SetLength(Email,255);

或者:

GetMem(Name,255);

GetMem(Email,255);

然后再能使用Name和Email变量。

转载于:https://www.cnblogs.com/bsoom/archive/2009/11/14/1603041.html

public static string WordsToString(int[] words) { if (words == null || words.Length == 0) return string.Empty; var sb = new StringBuilder(); foreach (int word in words) { // 提取低8位(LSB)→ 第一个字符 byte lowByte = (byte)(word & 0xFF); if (lowByte == 0) break; // 遇到空字符终止 sb.Append((char)lowByte); // 提取高8位(MSB)→ 第二个字符 byte highByte = (byte)((word >> 8) & 0xFF); if (highByte == 0) break; // 遇到空字符终止 sb.Append((char)highByte); } return sb.ToString(); } public static int[] StringToWords(string str, int minLength = 0) { if (string.IsNullOrEmpty(str)) str = "\0"; // 空字符串需包含终止符 // 换为ASCII字节数组(仅支持ASCII字符) byte[] bytes = Encoding.ASCII.GetBytes(str); // 添加字符串终止符 \0(确保以0x0000结尾) byte[] withNull = new byte[bytes.Length + 1]; Buffer.BlockCopy(bytes, 0, withNull, 0, bytes.Length); withNull[bytes.Length] = 0; // 确保字节数组长度为偶数(每2字节=1个字) if (withNull.Length % 2 != 0) { Array.Resize(ref withNull, withNull.Length + 1); withNull[withNull.Length - 1] = 0; } // 按小端序组合:[低地址字节, 高地址字节] → [LSB, MSB] int[] words = new int[withNull.Length / 2]; for (int i = 0; i < withNull.Length; i += 2) { words[i / 2] = withNull[i] | (withNull[i + 1] << 8); } // 按需填充到最小长度(如PLC固定数组长度) if (minLength > 0 && words.Length < minLength) { Array.Resize(ref words, minLength); for (int i = words.Length; i < minLength; i++) words[i] = 0; } return words; } 以上为在C#欧姆龙PLC通讯协议中, int[]数组string类型相互换的函数,麻烦进行大量数据的验证以确保其换逻辑是正确的;我需要使用在PLC读写前后的数据换逻辑里
最新发布
08-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值