Các anh ai biết có thể giải thích giúp em SizeOf() memory với

Liên hệ QC

thuyyeu99

Trùm Nhiều Chuyện
Tham gia
6/6/08
Bài viết
1,729
Được thích
874
Nếu em dùng api move ... SizeOf(string) để move sizeof(double) được không?.

Cảm ơn các anh
 
Nếu em dùng api move ... SizeOf(string) để move sizeof(double) được không?.
Một câu cụt lủn như thế thì chịu không biết ý bạn thế nào.

Nếu chỉ 1 dòng cụt lủn thì khó có thể đoán ý bạn. Cũng như "bài trước" bạn chỉ tung lên 1 dòng thì không ai đoán được nguyên nhân lỗi đâu. Mà đoán được thì hơi khó. Chỉ khi tung lên toàn bộ code từ A đến Z thì may ra có người chỉ ra được nguyên nhân sảy ra lỗi.

Chỗ nào cần nhập số thì cứ nhập đúng số thôi chứ lăn tăn gì chuyện SizeOf(string), SizeOf(double) hay SizeOf(Variant).

Variant có độ lớn 16 bai, vậy nếu bạn có mảng 10 Variant thì độ lớn của mảng là 10*16 = 160 bai. Nếu bạn cần truyền 160 thì cứ truyền 160 thôi. Còn nếu bạn muốn dùng SizeOf thì nhập 10*4*SizeOf(string), 10*2*SizeOf(double), 10*SizeOf(Variant) đều được vì 3 biểu thức đều trả về con số 160.

Còn nếu bạn muốn hiểu về SizeOf thì ...

SizeOf là hàm trả về một con số. Vậy thì dùng sao cho con số trả về là chính xác là được.

Để hiểu ý tôi cho ví dụ.
1. Xác định dòng cuối cùng có dữ liệu ở cột A :
Mã:
dong = Sheet1.Cells(Rows.Count, "A").End(xlUp).Row

2. Xác định cột cuối có dữ liệu ở dòng 1
Mã:
cot = Sheet1.Cells(1, Columns.Count).End(xlToLeft).Column

Thế nếu trong trường hợp 1 bạn dùng xlToLeft có được không? Thực ra End chỉ đòi hỏi, chỉ chờ đợi 1 con số. Chỉ phải nhập đúng con số thôi chứ nó có phân biệt con số đó lấy từ kho của công ty A hay từ vườn của bà B đâu. Cứ đúng con số là được.
Mã:
dong = Sheet1.Cells(Rows.Count, "A").End(xlToLeft - 3).Row
Thế thôi.

Tóm lại chỗ cần nhập con số thì cứ làm sao cho con số đúng là được.

Lần đầu tiên thấy API có MOVE. Thế mà lâu nay tôi vẫn nghĩ là MOVE của Delphi cơ đấy.

Tất nhiên phải hiểu SizeOf.

Để xét ví dụ ta giả thiết là ta xét system 32 bit.

Ví dụ
var
a: string;
b: double;
c: integer;
d: string[30];
e: ShortString;
f: array[0..16] of Char;
...
a := 'ngay mai em di';
memo1.lines.add(inttostr(SizeOf(a))); // 4
memo1.lines.add(inttostr(SizeOf(b))); // 8
memo1.lines.add(inttostr(SizeOf(c))); // 4
memo1.lines.add(inttostr(SizeOf(d))); // 31
memo1.lines.add(inttostr(SizeOf(f))); // 17
memo1.lines.add(inttostr(SizeOf(e))); // 256
memo1.lines.add(inttostr(SizeOf(String))); // 4
memo1.lines.add(inttostr(SizeOf(double))); // 8
memo1.lines.add(inttostr(SizeOf(integer)));// 4
memo1.lines.add(inttostr(SizeOf(DWORD))); // 4
memo1.lines.add(inttostr(SizeOf(Form1))); // 4
memo1.lines.add(inttostr(SizeOf(Memo1))); // 4

Kết quả lần lượt là 4, 8, 4, 31, 17 (5 kết quả đầu) vì các biến a, b, c, d, f đòi hỏi số bai là bằng từng ấy.

Kết quả lần lượt là 256, 4, 8, 4, 4, 4, 4 vì đó là số bai mà các biến có kiểu ShortString, String, Double, Integer, DWORD, Object, Object đòi hỏi.

Kiểu ShortString luôn được phân 256 bai cho dù tùy từng thời điểm mà độ lớn của chuỗi có thể ngắn hơn rất nhiều. Biến ShortString luôn được phân cho 256 bai, trong đó bai đầu tiên được dùng để nhớ độ dài hiện hành của chuỗi, và chuỗi chỉ có thể dài nhất là 255 ký tự.

Biến d và f được phân cho 31 và 17. Dễ hiểu.

Tại sao chỉ có 4 bai được phân cho biến a? Thực ra một chuỗi bất kỳ thì không thể biết nó sẽ có độ lớn bao nhiêu để phân bộ nhớ cho nó. Vì thế "người ta" sẽ làm như sau:
- ở đâu đó trong bộ nhớ, vd. ở địa chỉ abc trong bộ nhớ, sẽ được "đặt đơn" 4 bai cho biến a.
- khi chuỗi a được thiết lập giá trị cụ thể thì ở đâu đó trong bộ nhớ, vd. ở địa chỉ xyz trong bộ nhớ, Manager Memory của Delphi sẽ phân cho một vùng đủ lớn để ghi chuỗi hiện hành.
- địa chỉ trong bộ nhớ của chuỗi hiện hành, tức xyz, được ghi vào 4 bai ở địa chỉ abc.

Nói nôm na thì a chỉ có 4 bai và ghi nhớ địa chỉ hiện hành của chuỗi, còn bản thân chuỗi nằm ở địa chỉ khác.

Nếu a thay đổi giá trị chuỗi nhiều lần thì địa chỉ xyz có thể thay đổi (chuỗi a thay đổi địa chỉ tạm trú) và địa chỉ mới (chỉ là con số) sẽ được ghi vào 4 bai ở địa chỉ abc trong bộ nhớ.

String trong VBA tương tự.
Dim a As String

thì thực ra a chỉ được phân cho 4 bai, giả sử 4 bai được phân cho a nằm ở địa chỉ abc trong bộ nhớ. Chuỗi sẽ được ghi ở địa chỉ xyz trong bộ nhớ, và giá trị xyz sẽ được ghi vào 4 bai nằm ở địa chỉ abc. Nói nôm na thì chuỗi tạm trú ở địa chỉ xyz (trong bộ nhớ) còn biến a tạm chú ở địa chỉ abc, và a chỉ có nhiệm vụ nhớ giá trị xyz thôi.

Trong VBA thì VarPtr(a) trả về địa chỉ của biến a, tức giá trị abc. StrPtr(a) trả về địa chỉ tạm trú của chuỗi, tức giá trị xyz. Khi bạn muốn đọc ra chuỗi thì bạn viết vd. MsgBox a, nhưng sau cánh gà thì đã có những bước sau được thực hiện: nhẩy tới địa chỉ abc, tức nhẩy tới chỗ mà a tạm chú -> đọc ra 4 bai -> nhẩy tới địa chỉ bằng giá trị của 4 bai vừa đọc được, tức xyz, và đọc ra chuỗi.

Tất cả những cái tôi viết ở trên đều được làm sau cánh gà bởi code, Manager Memory Delphi (VBA). Bạn biết thì rất tốt, mà không biết cũng không sao. Bạn cứ
Dim a As String
a = "Ngay mai em đi."
MsgBox a

mà không cần biết sau cánh gà code và Manager Memory đã làm việc cật lực như thế nào để có kết quả dâng cho bạn. Bạn không cần biết là mỗi lần a thay đổi giá trị thì có thể nó sẽ thay đổi địa chỉ tạm trú trong bộ nhớ. Về phương diện người dùng bạn chỉ cần có giá trị mà không cần biết nó được "người ta" lấy từ đâu, lấy như thế nào. Tương tự như bạn chỉ thấy cô diễn viên má hồng môi đỏ mắt long lanh trên sân khấu, nhưng bạn không biết, không quan tâm, những ai sau cánh gà và đã đổ mồ hôi, thoa phấn má, tô môi, chải tóc, trang điểm như thế nào, để dâng cho bạn một cô diễn viên như thế.

String (long string) trong Delphi thực ra là Pointer. Bạn có thể viết
var
P: PChar;
...
a := 'Ngay mai em di.';
P := PChar(a);
showmessage(P^);

hoặc

a := 'Ngay mai em di.';
P := Pointer(a);
showmessage(P^);

đều được. Đều hiển thị "N".

Nhưng nếu bạn viết

d := 'Ngay mai em di.';
P := PChar(d);

hoặc

e := 'Ngay mai em di.';
P := PChar(e);

thì sẽ có lỗi "Invalid typecast"
 
Lần chỉnh sửa cuối:
Một câu cụt lủn như thế thì chịu không biết ý bạn thế nào.

Nếu chỉ 1 dòng cụt lủn thì khó có thể đoán ý bạn. Cũng như "bài trước" bạn chỉ tung lên 1 dòng thì không ai đoán được nguyên nhân lỗi đâu. Mà đoán được thì hơi khó. Chỉ khi tung lên toàn bộ code từ A đến Z thì may ra có người chỉ ra được nguyên nhân sảy ra lỗi.

Chỗ nào cần nhập số thì cứ nhập đúng số thôi chứ lăn tăn gì chuyện SizeOf(string), SizeOf(double) hay SizeOf(Variant).

Variant có độ lớn 16 bai, vậy nếu bạn có mảng 10 Variant thì độ lớn của mảng là 10*16 = 160 bai. Nếu bạn cần truyền 160 thì cứ truyền 160 thôi. Còn nếu bạn muốn dùng SizeOf thì nhập 10*4*SizeOf(string), 10*2*SizeOf(double), 10*SizeOf(Variant) đều được vì 3 biểu thức đều trả về con số 160.

Còn nếu bạn muốn hiểu về SizeOf thì ...

SizeOf là hàm trả về một con số. Vậy thì dùng sao cho con số trả về là chính xác là được.

Để hiểu ý tôi cho ví dụ.
1. Xác định dòng cuối cùng có dữ liệu ở cột A :
Mã:
dong = Sheet1.Cells(Rows.Count, "A").End(xlUp).Row

2. Xác định cột cuối có dữ liệu ở dòng 1
Mã:
cot = Sheet1.Cells(1, Columns.Count).End(xlToLeft).Column

Thế nếu trong trường hợp 1 bạn dùng xlToLeft có được không? Thực ra End chỉ đòi hỏi, chỉ chờ đợi 1 con số. Chỉ phải nhập đúng con số thôi chứ nó có phân biệt con số đó lấy từ kho của công ty A hay từ vườn của bà B đâu. Cứ đúng con số là được.
Mã:
dong = Sheet1.Cells(Rows.Count, "A").End(xlToLeft - 3).Row
Thế thôi.

Tóm lại chỗ cần nhập con số thì cứ làm sao cho con số đúng là được.

Lần đầu tiên thấy API có MOVE. Thế mà lâu nay tôi vẫn nghĩ là MOVE của Delphi cơ đấy.

Tất nhiên phải hiểu SizeOf.

Để xét ví dụ ta giả thiết là ta xét system 32 bit.

Ví dụ
var
a: string;
b: double;
c: integer;
d: string[30];
e: ShortString;
f: array[0..16] of Char;
...
a := 'ngay mai em di';
memo1.lines.add(inttostr(SizeOf(a))); // 4
memo1.lines.add(inttostr(SizeOf(b))); // 8
memo1.lines.add(inttostr(SizeOf(c))); // 4
memo1.lines.add(inttostr(SizeOf(d))); // 31
memo1.lines.add(inttostr(SizeOf(f))); // 17
memo1.lines.add(inttostr(SizeOf(e))); // 256
memo1.lines.add(inttostr(SizeOf(String))); // 4
memo1.lines.add(inttostr(SizeOf(double))); // 8
memo1.lines.add(inttostr(SizeOf(integer)));// 4
memo1.lines.add(inttostr(SizeOf(DWORD))); // 4
memo1.lines.add(inttostr(SizeOf(Form1))); // 4
memo1.lines.add(inttostr(SizeOf(Memo1))); // 4

Kết quả lần lượt là 4, 8, 4, 31, 17 (5 kết quả đầu) vì các biến a, b, c, d, f đòi hỏi số bai là bằng từng ấy.

Kết quả lần lượt là 256, 4, 8, 4, 4, 4, 4 vì đó là số bai mà các biến có kiểu ShortString, String, Double, Integer, DWORD, Object, Object đòi hỏi.

Kiểu ShortString luôn được phân 256 bai cho dù tùy từng thời điểm mà độ lớn của chuỗi có thể ngắn hơn rất nhiều. Biến ShortString luôn được phân cho 256 bai, trong đó bai đầu tiên được dùng để nhớ độ dài hiện hành của chuỗi, và chuỗi chỉ có thể dài nhất là 255 ký tự.

Biến d và f được phân cho 31 và 17. Dễ hiểu.

Tại sao chỉ có 4 bai được phân cho biến a? Thực ra một chuỗi bất kỳ thì không thể biết nó sẽ có độ lớn bao nhiêu để phân bộ nhớ cho nó. Vì thế "người ta" sẽ làm như sau:
- ở đâu đó trong bộ nhớ, vd. ở địa chỉ abc trong bộ nhớ, sẽ được "đặt đơn" 4 bai cho biến a.
- khi chuỗi a được thiết lập giá trị cụ thể thì ở đâu đó trong bộ nhớ, vd. ở địa chỉ xyz trong bộ nhớ, Manager Memory của Delphi sẽ phân cho một vùng đủ lớn để ghi chuỗi hiện hành.
- địa chỉ trong bộ nhớ của chuỗi hiện hành, tức xyz, được ghi vào 4 bai ở địa chỉ abc.

Nói nôm na thì a chỉ có 4 bai và ghi nhớ địa chỉ hiện hành của chuỗi, còn bản thân chuỗi nằm ở địa chỉ khác.

Nếu a thay đổi giá trị chuỗi nhiều lần thì địa chỉ xyz có thể thay đổi (chuỗi a thay đổi địa chỉ tạm trú) và địa chỉ mới (chỉ là con số) sẽ được ghi vào 4 bai ở địa chỉ abc trong bộ nhớ.

String trong VBA tương tự.
Dim a As String

thì thực ra a chỉ được phân cho 4 bai, giả sử 4 bai được phân cho a nằm ở địa chỉ abc trong bộ nhớ. Chuỗi sẽ được ghi ở địa chỉ xyz trong bộ nhớ, và giá trị xyz sẽ được ghi vào 4 bai nằm ở địa chỉ abc. Nói nôm na thì chuỗi tạm trú ở địa chỉ xyz (trong bộ nhớ) còn biến a tạm chú ở địa chỉ abc, và a chỉ có nhiệm vụ nhớ giá trị xyz thôi.

Trong VBA thì VarPtr(a) trả về địa chỉ của biến a, tức giá trị abc. StrPtr(a) trả về địa chỉ tạm trú của chuỗi, tức giá trị xyz. Khi bạn muốn đọc ra chuỗi thì bạn viết vd. MsgBox a, nhưng sau cánh gà thì đã có những bước sau được thực hiện: nhẩy tới địa chỉ abc, tức nhẩy tới chỗ mà a tạm chú -> đọc ra 4 bai -> nhẩy tới địa chỉ bằng giá trị của 4 bai vừa đọc được, tức xyz, và đọc ra chuỗi.

Tất cả những cái tôi viết ở trên đều được làm sau cánh gà bởi code, Manager Memory Delphi (VBA). Bạn biết thì rất tốt, mà không biết cũng không sao. Bạn cứ
Dim a As String
a = "Ngay mai em đi."
MsgBox a

mà không cần biết sau cánh gà code và Manager Memory đã làm việc cật lực như thế nào để có kết quả dâng cho bạn. Bạn không cần biết là mỗi lần a thay đổi giá trị thì có thể nó sẽ thay đổi địa chỉ tạm trú trong bộ nhớ. Về phương diện người dùng bạn chỉ cần có giá trị mà không cần biết nó được "người ta" lấy từ đâu, lấy như thế nào. Tương tự như bạn chỉ thấy cô diễn viên má hồng môi đỏ mắt long lanh trên sân khấu, nhưng bạn không biết, không quan tâm, những ai sau cánh gà và đã đổ mồ hôi, thoa phấn má, tô môi, chải tóc, trang điểm như thế nào, để dâng cho bạn một cô diễn viên như thế.

String (long string) trong Delphi thực ra là Pointer. Bạn có thể viết
var
P: PChar;
...
a := 'Ngay mai em di.';
P := PChar(a);
showmessage(P^);

hoặc

a := 'Ngay mai em di.';
P := Pointer(a);
showmessage(P^);

đều được. Đều hiển thị "N".

Nhưng nếu bạn viết

d := 'Ngay mai em di.';
P := PChar(d);

hoặc

e := 'Ngay mai em di.';
P := PChar(e);

thì sẽ có lỗi "Invalid typecast"
Cảm ơn anh rất nhiều.
Em co lên mạng tìm hiểu rồi mà dùng google dịch em đọc khó hiểu quá.

Variant có độ lớn 16 bai, vậy nếu bạn có mảng 10 Variant thì độ lớn của mảng là 10*16 = 160 bai. Nếu bạn cần truyền 160 thì cứ truyền 160 thôi. Còn nếu bạn muốn dùng SizeOf thì nhập 10*4*SizeOf(string), 10*2*SizeOf(double), 10*SizeOf(Variant) đều được vì 3 biểu thức đều trả về con số 160.
Tức là em chỉ cần xác định số byte chính xác. Nếu số byte dư, hay thiếu thì chắc lỗi phải không anh.
Tự cái Array là multi dynamic Array nên em chưa biết tính toán số Byte sao cho chinh xác
 
Cảm ơn anh rất nhiều.
Em co lên mạng tìm hiểu rồi mà dùng google dịch em đọc khó hiểu quá.


Tức là em chỉ cần xác định số byte chính xác. Nếu số byte dư, hay thiếu thì chắc lỗi phải không anh.
Tự cái Array là multi dynamic Array nên em chưa biết tính toán số Byte sao cho chinh xác
Cho dù VBA hay Delphi, Move hay không Move thì tất cả mọi tham số đều phải truyền chính xác. Move có 3 tham số thì cả 3 đều phải chính xác. Thế thôi.
Nếu chắc chắn cả 3 tham số đều có giá trị đúng mà có lỗi thì lỗi sảy ra sau đó. Thường thì có dính dáng tới memory. Nếu không có toàn bộ code từ A đến Z thì bó tay.
 
Dạ em hiểu ý anh rồi
 
Anh @batman1 cho em hỏi xíu nữa nhé
ví dụ VarPtr(a) có địa chỉ là 2420340 mà em thấy người ta VarPtr(a) + 8 = 2420348 mục đích để làm gì vậy anh
 
Bạn đang hỏi biến a kiểu là variant phải không? Biến variant có 2 byte đầu tiên chứa kiểu dữ liệu, tùy theo kiểu dữ liệu mà từ byte thứ 8 trở đi chứa giá trị hoặc địa chỉ của nội dung lưu trong biến a.
 
Bạn đang hỏi biến a kiểu là variant phải không? Biến variant có 2 byte đầu tiên chứa kiểu dữ liệu, tùy theo kiểu dữ liệu mà từ byte thứ 8 trở đi chứa giá trị hoặc địa chỉ của nội dung lưu trong biến a.
Đúng rồi nó là kiểu variant. cám ơn bạn
 
Hồi xưa tôi học nguồn chủ yếu là help. Bây giờ trên mạng cũng có nhiều. Nhưng nhiều người lại không chịu đọc help.
Học mà không chịu khó đọc help thì hơi lạ. Kiến thức nằm ngay bên cạnh, sao lại phải đi hỏi.
Không biết Delphi bây giờ ra sao nhưng help Delphi 5

help.JPG
 
Hồi xưa tôi học nguồn chủ yếu là help. Bây giờ trên mạng cũng có nhiều. Nhưng nhiều người lại không chịu đọc help.
Học mà không chịu khó đọc help thì hơi lạ. Kiến thức nằm ngay bên cạnh, sao lại phải đi hỏi.
Không biết Delphi bây giờ ra sao nhưng help Delphi 5

View attachment 229683
Em nhờ ông Google dịch dùm, nhiều lúc nó mong lung quá hihi. Bởi vậy hồi xưa không chịu học tiếng anh tốt
Với lại em không có học tin học, nhiều cái đụng vô mới mò khi biết rồi Ah thì ra đây là kiến thức cơ bản><<...,
 
Lần chỉnh sửa cuối:
Tôi cũng đã viết trên GPE:

Khoảng 6 năm 9 tháng trước trong bài #2


variant1.JPG

Hơn 2 năm trước trong bài #859


variant3.JPG

Nói vắn tắt thì 2 bai đầu (1 Word) là ghi VarType. Tiếp theo là 6 bai (3 Word) là reserved. 8 bai cuối là dữ liệu. Vd. nếu typ là numeric thì 8 bai sau là giá trị của numeric. Nếu vd. typ là string thì chỉ 4 bai là địa chỉ của string, còn bản thân string tạm trú ở nơi khác trong bộ nhớ. Nêu typ là Object thì cũng chỉ 4 bai là địa chỉ của Object tạm trú ở nơi khác. Những 4 bai này là Pointer tới string hoặc Object. Nhưng phải dùng 8 bai sau vì trong trường hợp numeric thì giá trị đọc luôn từ Variant. Mà khi typ là numeric DOUBLE thì double dùng 8 bai.
 
Cái này phải tiêu hóa từ từ đây :type: , hihihi cám ơn anh nhiều @$@^#.
 
Hôm Mạnh có thử quậy ADO sử dụng phương thức Rst.GetRows
lấy dữ liệu cái Array 2D đó vào bộ nhớ xong gán xuống Sheet ... mục đích là bỏ qua 2 dòng For next xem nó như thế nào ???!!!

mò diết API + Linh tinh thì cuối cùng nó chỉ về mấy cái link GPE + nhiều nơi khác nó cũng cứ nói linh tinh ... cuối cùng cũng đang bỏ đó
Nhiều lúc mở help ra coi thấy nó rối hơn vì kiến thức của mình chưa đủ hiểu Help ... mò các VD mẫu diết xong mở help ra coi mới bất chợt thấy được ???!!!
coi bộ vậy chứ help trong chừng mực nào đó khó nhai lắm :D :p
 
Lần chỉnh sửa cuối:
Cái này em mò hông có liên quan gì ADO hết heheheh, cái này chủ yếu thắt mắt ArrayVariant thôi.
Anh Mạnh cũng trùm mò chứ có chịu thua ai đâu kkk
 
Bạn có thể sử dụng hàm API CopyMemory để lấy các giá trị tại địa chỉ trong bộ nhớ để thử các trường trong biến variant. Ví dụ:
Mã:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Sub test1()
    Dim a, Vtype&, arr(1 To 10) As Integer, addr&
   'Variant a chua gia tri String
    a = "abc"
    CopyMemory Vtype, ByVal VarPtr(a), 2
    CopyMemory addr, ByVal VarPtr(a) + 8, 4
    CopyMemory ByVal VarPtr(arr(1)), ByVal addr, 6
End Sub
Sub test2()
    Dim a, Vtype&, arr(1 To 10) As Byte, lng&
    'Variant a chua gia tri Long
    a = 1000&
    CopyMemory Vtype, ByVal VarPtr(a), 2
    CopyMemory lng, ByVal VarPtr(a) + 8, 4
End Sub
Khi chạy test1 ta thấy, 4 bytes tại địa chỉ VarPtr(a)+8 sẽ chứa địa chỉ của chuỗi unicode "abc" còn giá trị của biến lng sẽ được gán bằng số Long 1000.
 
Hihihi em còn phải đọc lại các bài trong mục này nhiều lần rồi.
Cảm ơn các anh
 
coi bộ vậy chứ help trong chừng mực nào đó khó nhai lắm :D :p
Đọc help suông không giúp được gì đâu.

Luôn phải viết code để "mục sở thị". Kiểm tra xem có đúng như help viết không. Nếu chưa đúng thì đọc lại help xem mình đã hiểu đúng và truyền đúng tham số không. Rồi sửa và test. Cứ thế cho đến lúc hiểu và làm đúng.

Về cấu trúc Variant cũng thế. Đọc help thấy nói là 2 bai đầu là typ vậy viết code đọc ra 2 bai đầu rồi so sánh với giá trị trả về bởi VarType. Thấy help nói là 8 bai cuối của cấu trúc là ... string thì đọc ra 8 bai đó rồi nhẩy tới địa chỉ được trả về trong 8 bai đó rồi đọc thôi.

Để đọc memory thì bạn đã biết API CopyMemory. Địa chỉ mà từ đó đọc "2 bai và 8 bai kia" được trả về bởi VarPtr. Đọc help thấy nói là StrPtr trả về địa chỉ của chuỗi ở dạng unicode? Thì dùng CopyMemory đọc từ địa chỉ được trả về bởi StrPtr để xem chuỗi có đúng (tất nhiên ở dạng unicode) như mình đã nhập không. Đọc 8 bai kia rồi so sánh với StrPtr. Các hàm VarPtr, StrPtr, CopyMemory thì bạn đã biết. Vậy thì viết code để kiểm nghiệm, để mục sở thị. Thế thôi.

Về code ví dụ thì trong bài # 859 tôi cũng đã đưa ra

testvar.JPG
 
Web KT
Back
Top Bottom