كيفية تعيين سلسلة (أو أنسيسترينغ) ثابت في تفاريك?
-
15-11-2019 - |
سؤال
أريد تمرير وسيطات التنسيق Args
في الشكل وظيفة.لقد وجدت بعض الأمثلة على ذلك ، ولكن لا أستطيع معرفة كيفية تعيين ثابت سلسلة في تفاريك عضو.فشل التعليمات البرمجية التالية على تجميع مع E2089 Invalid typecast
.
procedure TForm1.Button1Click(Sender: TObject);
var Arguments: array of TVarRec;
begin
SetLength(Arguments, 2);
Arguments[0].VInteger := 111;
Arguments[1].VAnsiString := PAnsiString('Text'); // I want to set this member
ShowMessage(Format('Decimal: %d, String: %s', Arguments));
end;
يمكن لأي شخص أن يقترح لي كيفية تعيين سلسلة (أو أنسيسترينغ) ثابت إلى عضو تفاريك ?أنا باستخدام دلفي 2009.
شكرا جزيلا
المحلول
ويبدو أن هذا العمل في ز:
var
Args: array[0..1] of TVarRec;
S: AnsiString;
U: UnicodeString;
begin
S := 'Hello';
U := 'world';
Args[0].VType := vtAnsiString;
Args[0].VAnsiString := Pointer(S);
Args[1].VType := vtUnicodeString;
Args[1].VUnicodeString := Pointer(U);
Writeln(Format('%s, %s!', Args));
end;
نصائح أخرى
فقط بلدي اثنين سنتا.إجابة توندريج صحيحة ، لكنني أردت فقط التأكيد على بعض النقاط.والتعليقات ليست مكانا جيدا للقيام بذلك.
يرجى أن يكون على علم بأن AnsiString
يجب الرجوع إليها خلال كل الوقت TVarRec
سيتم استخدامها.
على سبيل المثال ، إذا قمت بكتابة وظيفة إعداد مجموعة من TVarRec
, ، يجب عليك التأكد من أنك قمت بعمل نسخة مؤقتة من AnsiString
تم إنشاؤه داخل الوظيفة إلى متغير سيبقى حتى كل الوقت TVarRec
يتم استخدام مجموعة.وإلا قد يكون لديك بعض انتهاك الوصول العشوائي (وليس في كل مرة ، ولكن فقط عندما مم إعادة تعيين ansistring
الذاكرة).
على سبيل المثال ، الكود التالي هو غير صحيح:
type
TVarRec2 = array[0..1] of TVarRec;
procedure SetVarRec(a,b: integer; var Result: TVarRec2);
begin
Result[0].VType := vtAnsiString;
Result[0].VString := pointer(AnsiString(IntToStr(a)));
Result[1].VType := vtUnicodeString;
Result[1].VString := pointer(UnicodeString(IntToStr(b)));
end;
لأن AnsiString
و UnicodeString
سيتم تحرير المتغيرات المؤقتة عند انتهاء الإجراء ، و Results[].VString
سوف لا تزال تشير إلى تلك الذاكرة المحررة...
باستخدام فئة أو سجل مع بعض سلسلة خاصة مؤقتة قد تفعل خدعة:
type
TMyVar2 = record
private
tmpA: AnsiString;
tmpB: UnicodeString;
public
VarRec: TVarRec2;
procedure SetVarRec(a,b: integer);
end;
procedure TMyVar2.SetVarRec(a,b: integer);
begin
VarRec[0].VType := vtAnsiString;
tmpA := AnsiString(IntToStr(a));
VarRec[0].VString := pointer(tmpA);
VarRec[1].VType := vtUnicodeString;
tmpB := UnicodeString(IntToStr(b));
VarRec[1].VString := pointer(tmpB);
end;
بالطبع ، في البرنامج الخاص بك قد يكون لديك فئة موجودة بالفعل.في هذه الحالة ، من الأفضل استخدام طريقة وبعض السلاسل المؤقتة الخاصة.لكي تكون الطريقة آمنة متعددة الخيوط (أي.إعادة المشارك) يجب عليك تقديم السلاسل المؤقتة كمعلمات...
أستخدم هذه الخدعة للحصول على مجموعة ديناميكية صالحة من TVarData
تحتوي على بعض AnsiString
المحتوى في فئة.في الواقع, TVarData
و TVarRec
كلاهما يستخدم هذا المؤشر غير المشار إليه للسلاسل ، والتي يمكن أن تكون مربكة.
كن على علم بأن القضايا التي تنطوي على pointer(S)
مثل البيانات يمكن أن يكون من الصعب تتبع.