زمان جاری : دوشنبه 31 اردیبهشت 1403 - 3:49 قبل از ظهر
نام کاربری : پسورد : یا عضویت | رمز عبور را فراموش کردم

تعداد بازدید 495
نویسنده پیام
abolfazl
آنلاین

Admin
ارسال‌ها : 15
عضویت: 15 /8 /1394
آموزش ساخت پلاگین

راهنمای توسعه افزونه
جهت یابی
معرفی
این یک انجمن پشتیبانی C / ++ نیست
سوالات متداول
سوالات سریع
شروع شدن
بررسی کد
فایل تعریف ماژول
"صادرات" چیست؟
توابع صادر شده
تعریف و ساختار
توابع AMX
مثالهای عملکرد Amx
ثبت نام بومیان
گرفتن یک رشته و طول آن
راه دیگری برای گرفتن یک رشته
نحوه تنظیم یک رشته
ریخته گری و بازگشت شناور
پارامترهای عبور از مرجع
گرفتن و اصلاح مقادیر آرایه
تماس تلفنی
تماس با بومی ها و تماس های تلفنی
فراخوانی
شروع شدن
اضافه کردن بومیان SA-MP
تماس با بومیان
هوابردن تماس ها
بسته شدن
با تشکر ویژه




معرفی


من تصمیم گرفتم این موضوع را برای پاسخ دادن به مسائل و سوالاتی که اغلب درباره توسعه پلاگین سوال می کنند، تعیین کنم. وقتی C / ++ یا SDK پلاگین به کار میرود، من هیچکدام از آنها را ندارم. به سادگی به اشتراک گذاشتن آنچه که در طول زمان خود برای توسعه افزونهها یاد گرفتم. امیدوارم هنگامی که این موضوع انجام شود، بیشتر از یک پروژه گروهی با دیگر کاربران همراه است که اطلاعاتی را که ممکن است به آن نرساند یا فراموش کنند شامل شود. این موضوع بسیار مهمی است که می توانید آن را پوشش دهید، بنابراین به کمک نیاز دارم.


این یک انجمن پشتیبانی C / ++ نیست


به نظر می رسد که افراد در هنگام ارسال این مطلب بسیار گیج می شوند. من دیده ام بسیاری از افراد از سؤالات کاملا معتبر در مورد افزونه SDK سوال می کنند که در نهایت با چندین "این یک انجمن پشتیبانی C / ++ نیست!" نقل قول فقط به این معنی است که انتظار می رود کسی از زبان ها مطلع باشد، به این معنا نیست که آنها مجاز به ارائه سوالات درباره SDK واقعی نیستند. بین درخواستی از یک اشارهگر تفاوت وجود دارد و از چیزی مانند چگونگی ایجاد callbacks استفاده می کند!


با این گفتن سایت ها و انجمن های عالی برای آموزش و پاسخ به سوالات در مورد C / ++ وجود دارد. در اینجا چند مورد استفاده شده است:


این سایت ها آموزش های عالی برای یادگیری از:


cprogramming.com
cplusplus.com
learncpp.com


اگر شما در مورد C / ++ گیر کرده اید، می توانید از یکی از این انجمن ها برای درخواست کمک استفاده کنید:


dreamincode.net
stackoverflow.com
سوالات متداول
سوالات سریع


سوال : چگونه پلاگین ها ساخته می شوند؟
پاسخ : پلاگین ها در C / ++ با استفاده از SDK پلاگین ساخته می شوند. این پرسش های متداول بر این عقیده است که شما C / ++ را در حال حاضر می شناسید و بعدها اطلاعاتی در مورد SDK واقعی ارائه می دهد.


سوال : آیا می توانم افزونه ای در یک زبان برنامه نویسی غیر از C / ++ ایجاد کنم؟
پاسخ: در نظریه امکان پذیر است تلاش شده است که SDK پلاگین SA-MP را به زبان برنامه نویسی D بفرستد که از رابط کاربری باینری برنامه C پشتیبانی می کند. در حالی که من هرگز یک پلاگین کاملا کار شده در نوشته D ندیده ام، این مثال به امکان نوشتن پلاگین ها در زبان هایی که از C / ++ پشتیبانی می کنند روشن می کند. همچنین در مورد احتمال پیوستن صحبت شده است، اما من هنوز برای دیدن هر گونه حمایت از این وجود دارد.


سوال : چگونه میتوانم پلاگین خود را چندپردازنده کنم (موجود در لینوکس و ویندوز)؟
پاسخ : لینوکس و ویندوز دو سیستم عامل مختلف هستند که هر دو API ها و پیاده سازی های متفاوت خود را دارند. گرفتن کد خود برای کار بر روی هر دو سیستم عامل به این معنی است که شما باید از کد مستقل سکوی یا یک چارچوب استفاده کنید که همه چیز را با سیستم عاملهای شما مرتبط می کند. پس از اطمینان از اینکه کد شما به هیچ یک از API ها تکیه نمی کند، شما مجبورید کد خود را در محیط مورد نظر خود کامپایل کنید (یک بار دیگر این راهنما فرض می کند که می دانید چطور این کار را انجام دهید).


سوال : آیا می توانم افزونه من از هک کردن حافظه استفاده کنم؟
پاسخ : صادقانه این یک نوع خاکستری است. به نظر می رسد که استفاده از هک کردن حافظه برای فراخوانی های تماس یا توابع فراخوانی کاملا قابل قبول است. به نظر می رسد هر چیزی که حافظه سرور را تغییر می دهد خاموش باشد ( این را ببینید). اگر برنامه ریزی خود را در ساخت پلاگین که نیاز به استفاده از حافظه هک برای هر چیزی دیگر تماس های متوقف کردن تماس و یا عملکرد تماس، قبل از دست از اجازه و قبل از ارسال، تایید کنید؛ این صادقانه بهترین راه برای پیدا کردن است!


سوال : آیا امکان پلاگین وجود دارد که ______ باشد؟
پاسخ: در اغلب موارد، هر ایده کاملا پیاده سازی شده است. ممکن است به یک برنامه مستقل نیاز داشته باشد که به پلاگین ارتباط برقرار کند، اما احتمالا ممکن است. سوالاتی مانند این نباید نوشته شود پاسخ شما را شنیده اید، اکنون حرکت کنید! این بخش درخواست افزونه نیست امیدوارم روزی باشد که سازندگان پلاگین به اندازه کافی برای ایجاد بخش یا موضوع چسبنده برای درخواست وجود داشته باشند (این راهنما برای معرفی و کمک به توسعه دهندگان پلاگین جدید طراحی شده است، بنابراین امیدوارم).


سوال : کدام IDE / کامپایلر باید برای ______ استفاده کنم؟
پاسخ : این کاملا به شماست! من شخصا از VC ++ 2010 استفاده خواهم کرد به عنوان ویندوز ایکس پی و کامپایلر، و در مورد استفاده از g ++ برای کامپایلر لینوکس برنامه ریزی کنم. فقط با گزینه های مختلف ظاهر می شود و ببینید که کدام یکی از بهترین ها را دوست دارید


سوال : یک فایل تعریف ماژول (.def) چیست؟
پاسخ : یک فایل تعریف ماژول یک فایل خاص در ویژوال استودیو IDE است که لینکر را با اطلاعات مربوط به برنامه مرتبط می کند. هنگامی که برای نوشتن پلاگین برای SA-MP می آید، ما فقط از عبارت "EXPORTS" استفاده می کنیم که اطلاعاتی را درباره توابع صادر شده ما ارائه می دهد. بعدا در این مقاله به این بیانیه خواهیم پرداخت.


سوال : هنگامی که یک پلاگین را منتشر می کنم، آیا باید آن منبع را داشته باشد؟
پاسخ : اگر چیزی در این انجمن منتشر کنید همیشه باید منبع آن را داشته باشید. پلاگینها هیچ استثنائی نیستند (مگر اینکه افزونه توسط یک توسعه دهنده تایید شود که بدون یک منبع ارسال شود - شاید یک ضد تقلب باشد؟).
شروع شدن


چند بار از شما خواسته شد "چگونه می توانم با توسعه افزونه شروع کنم؟" من تصمیم گرفتم این بخش را برای پاسخ به این سوال اضافه کنم! فقط به این دلیل که شما زبان را می دانید به این معنی نیست که شما بعد از همه چیز را در اطراف IDE می شناسید؛ من فکر می کنم که این امر به ویژه در مورد VC ++ 2010 صادق است. استودیو ویژوال می تواند جای بسیار مهیج برای کاربران جدید باشد. من به سختی فکر می کنم عادلانه آن فقط به شما اضافه کردن SDK پلاگین بدون نشان دادن شما در اطراف اول! مسنجر با صفحات املاک / لینک دهنده به راحتی می تواند مردم را ترساند، بنابراین من قصد دارم شما را از طریق آن هدایت کنید.


نکته: اگر تصمیم گرفتید از IDE / کامپایلر دیگری استفاده کنید که برای ویندوز اهداف دارد، شما از شانس نیستید! به نظر می رسد که تنها راه برای موفقیت توابع صادرات، استفاده از یک فایل تعریف ماژول (.DEF) است. من سعی کردم یک روش جایگزین را در این مقاله با استفاده از __declspec (dllexport) بگنجانم، اما این به سادگی به دلیل کنفرانس __stdcall تماس نگرفتن نامهای تابع صادر شده را مشاهده کرد (به اینجا مراجعه کنید ).




در اینجا دانلود شما برای این بخش نیاز دارید:


Visual C ++ 2010 Express : دانلود رایگان
Plugin SDK (Plain) : دانلود




اولین چیزی که ما می خواهیم انجام دهیم ایجاد یک پروژه جدید است. برای انجام این کار، فایل-> new-> project را انتخاب کنید.
هنگامی که یک پروژه جدید ایجاد می کنید، می خواهید به شما از نوع پروژه ای که می خواهید ایجاد کنید بپرسید. انتخاب پروژه Win32، نام پروژه را وارد کنید و برای ادامه ادامه دهید.
هنگامی که تنظیم پروژه شما مراقبت از این گفت و گو می شود باید ظاهر شود. برای ادامه ادامه دهید
پس از کلیک بر روی ادامه، باید این پنجره محاوره ای را که درخواست نوع و تنظیمات برنامه شما را می بیند، مشاهده کنید. برای نوع انتخاب DLL (کتابخانه پویا لینک) و برای تنظیمات پروژه خالی را انتخاب کنید. پس از پایان کار، دکمه پایان را در پایین فشار دهید.


چیزی که ما میخواهیم انجام دهیم این است که به explorer راه حل ما برویم. راه حل اکسپلورر معمولا در سمت چپ IDE قرار دارد. اگر شما به طور تصادفی آن را غیرفعال کرده اید می توانید آن را با فشار دادن CTRL + ALT + L یا با انتخاب View-> windows-> explorer explorer دوباره فعال کنید. با کلیک بر روی نام پروژه (در این مثال «آزمون») راست کلیک کرده و گزینه Properties را انتخاب کنید.
هنگامی که صفحات اموال را می بینید، به ویژگی های پیکربندی-> لینک-> ورودی در سمت چپ حرکت می کنند. هنگامی که شما در آنجا هستید می خواهید یک فایل تعریف ماژول اضافه کنید. شما می توانید این فایل هر چیزی را که دوست دارید نامگذاری کنید تا زمانی که یک برنامه افزودنی ".def" در انتهای آن وجود داشته باشد. افراد معمولا فایل های def را پس از پروژه خود می نویسند. هنگامی که فایل تعریف شده خود را به نام "OK" نامگذاری کرده اید.
در حال حاضر همه ما باید انجام دهیم این است که فایل های خود را اضافه کنید (این شامل فایل تعریف ما!). برای اضافه کردن یک فایل به پروژه خود، دوباره به explorer راه حلی بروید، روی نام پروژه کلیک راست کنید، روی افزودن کلیک کنید، سپس آیتم جدید را انتخاب کنید. در این مثال ما فایل تعریف ما را اضافه خواهیم کرد. از آنجا که یک گزینه برای فایل های تعریف وجود ندارد، فقط یک فایل منبع (.cpp) را انتخاب کنید و نام پرونده تعریف ماژول را که تصمیم گرفته اید تایپ کنید ( توجه : مطمئن شوید که افزودنی ".def" را شامل می شود، دیگر عاقلانه ".cpp "افزونه اضافه خواهد شد!) پس از انجام این کار، یک فایل منبع برای پروژه به همان شیوه (به جز افزودن افزونه اضافی) را اضافه نکنید. اکثر مردم از نام "اصلی" برای فایل منبع اصلی استفاده می کنند.
قبل از شروع به اضافه کردن هر چیزی به دو فایل خالی در حال حاضر، باید SDK را به پروژه اضافه کنیم. اگر قبلا نتوانسته اید، SDK را از لینکی که در ابتدای این بخش ارائه شده است، دانلود کنید. پس از بارگیری آن، پوشه SDK را به دایرکتوری پروژه فعلی خود استخراج کنید. توجه داشته باشید این بخش اختیاری است: من شخصا دوست دارم فیلترها را برای سازماندهی تمام فایل ها و کد های خودم دوست دارم. یک فیلتر یک ابزار سازمانی در استودیوی ویژوال است که پوشه ها را در پروژه شما ایجاد می کند، اما پوشه های Windows مربوطه را ایجاد نمی کند (توصیه می شود برای ایجاد پوشه های مشابه). برای ایجاد فیلتر روی پروژه خود را در explorer-> add-> فیلتر جدید کلیک راست کنید و نامی را برای فیلتر خود انتخاب کنید (نام آن SDK در این مورد).
گام بعدی این است که همه فایلهای SDK را به پروژه فعلی اضافه کنیم. برای اضافه کردن فایل های موجود به یک پروژه، به درستی بر روی پوشه یا پروژه ای که می خواهید آنها را اضافه کنید، راست کلیک کنید و گزینه اضافه کردن -> آیتم موجود را انتخاب کنید. شما می خواهید همه چیزهایی که درون پوشه SDK در دایرکتوری پروژه شما هستند را اضافه کنید ( توجه : شما می توانید چندین فایل را با نگه داشتن Ctrl در حالی که با کلیک روی فایل ها برای اضافه کردن انتخاب می کنید را انتخاب کنید). برای یکپارچگی پوشه، ما یک فیلتر دیگر در داخل فیلتر SDK ایجاد می کنیم و آن را amx نام می دهیم. البته شما می خواهید همه محتویات پوشه SDK amx را به فیلتر amx اضافه کنید.


اکنون وقت آن است که این پلاگین را کامپایل کنیم! اگر به درستی دستورالعمل ها را دنبال کردید، باید فایل تعریف ماژول و فایل منبع را باز کنید اگر نه، به چند مرحله بروید و دستورالعمل ها را به دقت دنبال کنید. پیش بروید و اطلاعات زیر را در فایل های مربوطه کپی کنید و آن را بکشید. نگران نباشید اگر هیچ کدام از آن را درک نکنید، ما در بخش بعدی به آن همه چیز می پردازیم.


فایل منبع (* .cpp) :
پیاده روی کد:
#include "SDK amx amx.h"
#include "SDK plugincommon.h"




typedef void ( * logprintf_t ) ( فرمت char * ، ... ) ؛




logprintf_t logprintf؛
extern void * pAMXFunctions؛




سلول AMX_NATIVE_CALL HelloWorld ( AMX * AMX، سلول * params )
{
logprintf ( "این از پلاگین تست چاپ شد! بله!" ) ؛
بازگشت 1 ؛
}


PLUGIN_EXPORT int unsigned int PLUGIN_CALL پشتیبانی از ( )
{
بازگشت SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES؛
}


PLUGIN_EXPORT bool PLUGIN_CALL بار ( void ** ppData )
{
pAMXFunctions = ppData [ PLUGIN_DATA_AMX_EXPORTS ] ؛
logprintf = ( logprintf_t ) ppData [ PLUGIN_DATA_LOGPRINTF ] ؛


logprintf ( "* افزونه تست بارگذاری شد." ) ؛
بازگشت درست
}


PLUGIN_EXPORT void PLUGIN_CALL Unload ( )
{
logprintf ( "* افزونه تست تخلیه شد." ) ؛
}


AMX_NATIVE_INFO PluginNatives [ ] =
{
{ "HelloWorld" ، HelloWorld }
{ 0 ، 0 }
} ؛


PLUGIN_EXPORT int PLUGIN_CALL AmxLoad ( AMX * amx )
{
amx_Register بازگشت ( amx، PluginNatives، - 1 ) ؛
}




PLUGIN_EXPORT int PLUGIN_CALL AmxUnload ( AMX * amx )
{
بازگشت AMX_ERR_NONE؛
}


فایل تعریف ماژول (* .def)
کد:
صادرات
پشتیبانی
بار
بارگیری
AmxLoad
AmxUnload
بررسی کد


در این بخش، ما خواهیم دید برخی از تعاریف، ساختارها و عملکرد هایی که SDK Plugin SA-MP ارائه می دهد. قبل از شروع به درک راحت C / ++ باید به آن عمل کنید، همانطور که فقط اطلاعات مربوط به SDK را توضیح می دهم، هنگامی که ما در بخش های کد شده قرار می گیریم. از اینجا بیرون، هر دست دست نگه داشتن وجود ندارد!


فایل تعریف ماژول


قبل از اینکه نگاهی به کد ببریم، می خواهیم فایل تعریف ماژول ما را در بخش قبلی ببینیم. اول از همه، دقیقا یک پرونده تعریف ماژول چیست؟ ما یک ویژگی منحصر به فرد استودیویی ویژوال را می دانیم، اما دقیقا چه کاری انجام می دهد؟ ساده است! یک پرونده تعریف ماژول اطلاعاتی را برای لینک دهنده در مورد کد که در حال اتصال است فراهم می کند. قوانین و اظهارات زیادی وجود دارد که می تواند در این فایل ها استفاده شود، اما ما فقط در مورد بیانیه ی EXPORTS صحبت خواهیم کرد.


"صادرات" چیست؟


صادرات بیانیه است که به ما اجازه می دهد ... خوب، صادرات مواد به برنامه ما! چرا ما این کار را انجام می دهیم؟ از آنجا که ما باید آن را ساده به عنوان آن. توابع ما صادرات نقاط ورود در فایل DLL ما است. برنامه های کاربردی فقط می توانند توابع را در DLL ما که صادرات ما لمس می کنند. اگر ما آنها را صادر نکنیم، آنها به پرونده DLL خصوصی می شوند. ما هم اکنون نمی خواهیم این کار را انجام دهیم؟ نه. بنابراین ما همه چیز را که برنامه کاربردی به طور مستقیم دسترسی به آن را صادر می کنیم، صادر می کنیم.


توابع صادر شده


در حال حاضر 6 توابع وجود دارد که باید صادر شوند. ما از 5 نفر از آنها در داخل پروژه ما استفاده می کنیم که ما تنظیم کرده ایم. نگران نباشید در مورد تعاریف PLUGIN_EXPORT و PLUGIN_CALL که در اعلامیه های عملکرد مشاهده می کنید. ما در این مقاله با برخی از تعاریف مهم دیگر (که با متن سبز مشخص شده است) را پوشش می دهیم.


پشتیبانی از () این تابع به سرور می گوید که قابلیت های پلاگین ما بر چه چیزی بازمی گردد. به طور کلی ما فقط از 3 پرچم پشتیبانی در پلاگین ها استفاده می کنیم: SUPPORTS_VERSION ، SUPPORTS_AMX_NATIVES ، و SUPPORTS_PROCESS_TICK .
بار (void **) تابع Load بسیار ساده است. این زمانی است که افزونه بارگذاری می شود و یک آرایه از آدرس هایی که افزونه برای استفاده از آنها استفاده می شود، ارسال می شود. دو شاخص که ما معمولا استفاده می کنیم PLUGIN_DATA_AMX_EXPORTS است و PLUGIN_DATA_LOGPRINTF .
Unload () Unload وقتی پلاگین تخلیه می شود (سرور خاموش است) نامیده می شود.
AmxLoad (AMX *) این وقتی یک نمونه جدید AMX در سرور بارگذاری می شود، نامیده می شود. این برای هر filtercript / gamemode فراخوانی خواهد شد! به همین دلیل یک ایده خوب برای ذخیره یک مثال AMX برای کل پلاگین نیست، بلکه از یک صف / لیست / بردار استفاده کنید. در این تابع نیز توابع محلی سفارشی ما که مایل به ارائه PAWN هستند را ثبت می کنیم.
AmxUnload (AMX *) این تابع زمانی خوانده می شود که یک مثال AMX تخلیه شود. اگر نمونه های AMX را ذخیره می کنید، مطمئن شوید که آنها را حذف کرده اید. در غیر اینصورت مواردی برای gamemodes / filterscripts موجود ندارید
ProcessTick () ProcessTick یک تابع است که در هر تکرار حلقه سرور فراخوانی می شود. مردم معمولا از این تابع به عنوان یک روش مدیریت زمان استفاده می کنند، با پیگیری میزان کنه که گذشت. سرور SA-MP گفته است که زمان خواب 5 مگابایت است، بنابراین اگر 50 عدد کنده شود، ایده ای از زمان سپری شده (5 * 50 = 250ms) است. توجه : هر کسی که در پلاگین های خود از موضوعات استفاده می کند و نیاز به تعامل با PAWN دارد، باید از این تابع استفاده کند تا اطمینان حاصل شود که PAWN کار دیگری انجام نمی دهد!


تعریف و ساختار


در حال حاضر بخش سرگرم کننده می آید، ما می توانیم نگاهی به کد بیاندازیم! شما احتمالا از خفاش متوجه خواهید شد که ما از یک مثال کوچک از بخش قبلی استفاده از یک تن از تعاریف و ساختارها را داریم. اگر تاکنون پلاگین SA-MP را توسعه نداده اید، این می تواند بسیار گیج کننده و حتی تهدید کننده باشد. در این بخش برخی از نکات را در مورد این تعاریف و ساختارها خواهیم زد.


سلول یک سلول نوعی است که به راحتی قابل حمل است. PAWN پشتیبانی از اعداد صحیح 16، 32 و 64 بیتی را پشتیبانی می کند. سلول typedef همیشه اندازه درست خواهد بود در غیر اینصورت "int" ممکن است. به طور کلی با پلاگین SA-MP، این typedef همیشه یک عدد صحیح 32 بیتی خواهد بود. توجه: یک tyhedef "ucell" برای عدد صحیح بدون علامت وجود دارد، اما این به سختی مورد استفاده قرار می گیرد.
AMX_NATIVE_CALL این تعریف تماس را که توابع بومی ما استفاده می کند تعریف می کند. در حال حاضر آن را به هیچ چیز تعریف شده است، بنابراین پیش فرض استفاده می شود.
AMX نام این ساختار باید بسیار واضح باشد، نمونه آن AMX است. این ساختار دارای تن اطلاعات مربوط به بخش های داده همراه با تن دیگر اطلاعات مربوط به AMX است. این ساختار باید در تمام اعلامیه های عملکرد بومی همراه با اشاره گر سلولی به پارامترهای منتخب باشد؛ بدون این اطلاعات ما نمی دانیم چه اسکریپت بومی ما را می خواند و نه می دانیم چه اتفاقی افتاده است.
PLUGIN_EXPORT این به عنوان "PLUGIN_EXTERN_C" تعریف شده است.
PLUGIN_EXTERN_C اگر با استفاده از کامپایلر C ++ این به عنوان "extern" C "" تعریف شده است. این برای سازگاری با C است. C ++ چیزهایی مانند بارگذاری تابع را ارائه می دهد، بنابراین اطلاعات اضافی مانند تعداد / اندازه آرگومان ها با نام تابع ذخیره می شود، این به عنوان «نام منگل» نامیده می شود. هنگامی که این تعریف استفاده می شود، آن را به C + ++ می گوید تا از ارتباط C-style استفاده کند و از این طریق اجتناب از نام C ++ نام است.
PLUGIN_CALL این تعریف به C / ++ می گوید که کدام قرارداد تماس برای استفاده از توابع صادر شده ما استفاده می شود. اگر شما از یک پنجره هدفمند کامپایلر استفاده می کنید، این عبارت __stdcall تعریف شده است. در غیر این صورت آن را به عنوان هیچ چیز تعریف می کند و قرارداد پیش فرض استفاده می شود.
SUPPORTS_VERSION این تعریف باید در ماسک بیتی استفاده شود که توسط تابع «پشتیبانی ()» ما بازگردانده شده است. این پرچم برای بررسی سازگاری با سرور مورد استفاده قرار می گیرد.
SUPPORTS_AMX_NATIVES این یکی دیگر از تعریف است که باید توسط عملکرد "پشتیبانی ()" ما استفاده شود. هر افزونه ای که از توابع AMX استفاده می کند باید از این پرچم استفاده کند! بدون این پرچم یک خطای زمان اجرا 19 را به دلیل بومیان خود که با سرور ثبت نام نکردند (amx_Register) دریافت می کنید.
SUPPORTS_PROCESS_TICK آخرین پرچم ما برای عملکرد "پشتیبانی ()" ما است. اگر میخواهید از تابع «ProcessTick ()» استفاده کنید، باید این را به ماسک بیتی تابع «Supports ()» اضافه کنید.
PLUGIN_DATA_AMX_EXPORTS این به عنوان یک شاخص برای آرایه چند بعدی ای است که در Load بارگذاری می شود. این شاخص خاص جدول تابع AMX را نگه می دارد. تمام پلاگین ها باید از این شاخص برای تعیین آدرس جدول عملکرد به pAMXFunctions استفاده کنند.
PLUGIN_DATA_LOGPRINTF با این حال یک شاخص دیگر است که باید با آرایه چند بعدی مورد استفاده قرار گیرد که در بارگذاری قرار می گیرد. این شاخص نشانی از عملکرد logprintf است که اطلاعات را چاپ می کند و اطلاعات را به فایل ورود به سرور ذخیره می کند. اگر افزونه شما از این تابع استفاده کند، باید از این شاخص استفاده کنید تا آدرس را به اشارهگر تابع logprintf اختصاص دهید.
AMX_NATIVE_INFO این ساختار در ارتباط با amx_Register استفاده می شود. این شامل یک رشته است که نام جدید بومی شما را نشان می دهد و یک اشاره گر به آدرس آن است.


چند تعریف مهم دیگر که مربوط به اشتباهات عملکرد AMX هستند، وجود دارد، اما آنها قبلا در داخل هدر AMX ثبت شده اند. بنابراین به جای نوآوری چرخ، من فقط می خواهم این عدد را با تمام کدهای خطا و نظرات مربوط به آنها ارسال کنم.


توجه: هر تابع AMX، به استثنای amx_NativeInfo، یکی از این کدهای خطا را در صورت بروز یک مشکل به ارمغان می آورد.


پیاده روی کد:
enum
{
AMX_ERR_NONE،
/ * اولین کد 15 خطا برای کد خروج از ماشین انتزاعی * /
AMX_ERR_EXIT، / * خروج اجباری * /
AMX_ERR_ASSERT، / * ادعا نشد * /
AMX_ERR_STACKERR، / * پشته / برخورد پشته * /
AMX_ERR_BOUNDS، / * index out of bounds * /
AMX_ERR_MEMACCESS، / * دسترسی به حافظه نامعتبر * /
AMX_ERR_INVINSTR، / * دستورالعمل نامعتبر * /
AMX_ERR_STACKLOW، / * سرریز پشته * /
AMX_ERR_HEAPLOW، / * hood underflow * /
AMX_ERR_CALLBACK، / * هیچ فراخوانی callback یا callback نامعتبر * /
AMX_ERR_NATIVE، / * عملکرد بومی نتوانست * /
AMX_ERR_DIVIDE، / * تقسیم صفر * /
AMX_ERR_SLEEP، / * به حالت sleepmode بروید - کد را می توان دوباره راه اندازی کرد * /
AMX_ERR_INVSTATE، / * نامعتبر برای این دسترسی * /


AMX_ERR_MEMORY = 16 ، / * خارج از حافظه * /
AMX_ERR_FORMAT، / * فرمت فایل نامعتبر * /
AMX_ERR_VERSION، / * file برای نسخه جدید AMX * /
AMX_ERR_NOTFOUND، / * تابع یافت نشد * /
AMX_ERR_INDEX، / * پارامتر شاخص نامعتبر (نقطه ورود بد) * /
AMX_ERR_DEBUG، / * debugger نمی تواند اجرا شود * /
AMX_ERR_INIT، / * AMX مقداردهی اولیه نشده (یا دوبار مقدار دهی شده) * /
AMX_ERR_USERDATA، / * قادر به تنظیم فیلد داده کاربر (جدول کامل) * /
AMX_ERR_INIT_JIT، / * نمی تواند JIT * /
AMX_ERR_PARAMS، / * خطای پارامتر * /
AMX_ERR_DOMAIN، / * دامنه خطا، نتیجه بیان در محدوده مناسب نیست * /
AMX_ERR_GENERAL، / * خطای کلی (خطای ناشناخته یا غیر اختصاصی ) * /
} ؛
توابع AMX


توابع AMX به خوبی مستند شده اند در داخل راهنمای PAWN پیاده سازی، که می تواند در اینجا یافت می شود. به جای نوآوری چرخ و توضیح تمام توابع در کلمات خود من، من به سادگی آنها را در اینجا از راهنمای پیاده سازی کپی کنید، و آنها را کمی قابل ملاحظه تر؛ من معتقدم که این امر باعث می شود که مطالب بسیار قابل دسترسی باشد. با این توضیح، این بخش عمدتا یک مرجع برای بخش بعدی است که بر روی چیزی است که راهنمای برنامه نویسان وجود دارد، کد نمونه را متمرکز می کند. توجه: من فقط توابع را پوشش می دهم که فکر می کنم برای پلاگین ها حیاتی هستند (در حال حاضر). هر چیز دیگری را می توان در راهنمای پیاده سازی پیدا کرد، فقط مطمئن شوید که نسخه ای را که من در این بخش مرتبط کرده ام، استفاده می کنید!


کلید:


در این راهنما موجود است
در دسترس نیست




amx_allot


- رزرو فضای حیاط در ماشین انتزاعی


نحو :
کد:
int amx_Allot (AMX * amx، int cells، cell * amx_addr، cell ** phys_addr)؛
amx ماشین انتزاعی
سلول ها تعداد سلول ها برای رزرو.
amx_addr آدرس سلول اختصاص داده شده به عنوان برنامه پیاده (که در ماشین انتزاعی اجرا می شود) می تواند به آن دسترسی پیدا کند. phys_addr آدرس سلول برای برنامه های C / C ++ برای دسترسی.


یادداشت ها : در نسخه های پیشین پیاده، آرایه ها و رشته ها باید منتقل شوند
یک اسکریپت پس از صریحا اختصاص حافظه برای آن در پشته AMX.
در نسخه فعلی، این قابلیت تا حد زیادی جایگزین شده است
توسط توابع amx_PushArray و amx_PushString.
یک تابع پین تنها می تواند به حافظه داخل ماتریس انتزاعی دسترسی داشته باشد
چینی اگر یک پارامتر "به صورت مرجع" به یک پیاده منتقل شود
تابع، باید آدرس آن پارامتر را به amx_Exec منتقل کند.
علاوه بر این، آدرس خودش باید در محدوده آدرس باشد
ماشین انتزاعی نیز هست پیچیدگی اضافه شده این است که انتزاعی است
دستگاه از آدرس هایی استفاده می کند که نسبت به بخش داده ای از
ماشین انتزاعی و برنامه میزبان با استفاده از آدرس مربوط به
محیطی که سیستم عامل آن را فراهم می کند.
amx_Allot سلولهای حافظه را در داخل ماشین انتزاعی و
آن دو آدرس را باز می گرداند. پارامتر amx_addr آدرس است
متغیر مربوط به "بخش داده" ماشین انتزاعی؛
این مقدار است که شما باید به amx_Exec (از طریق amx_Push) منتقل کنید. Pa-
rameter phys_addr نشانی مربوط به برنامه میزبان را نگه می دارد
فضای آدرس بنابراین برنامه C / C ++ می تواند از این آدرس استفاده کند و نوشتن کند
به حافظه اختصاص داده شده.
پس از بازگشت amx_Exec، شما ممکن است بلوک حافظه (
تابع pledge که توسط amx_Exec نامیده می شود به آن نوشته شده است) و
در نهایت آن را با تماس amx_Release آزاد کنید.


همچنین ببینید: amx_Exec ، amx_PushArray ، amx_PushString ، amx_Release




amx_ctof


- بازیگران "سلول" به "شناور"


نحو:
کد:
[ شناور ] amx_ctof ([سلول] c)؛
ج ارزش برای بازیابی از نوع سلول به "شناور".


بازگشت: همان الگوی بیتی، اما در حال حاضر به عنوان نوع شناور شناخته شده است.


یادداشت ها: این ماکرو یک نوع سلولی را به نوع "شناور" تغییر می دهد بدون تغییر
الگوی بیتی یک نوع نرمال در C / C ++ حافظه را تغییر می دهد
نمایندگی بیان به طوری که ارزش عددی آن در IEEE
فرمت 754 نزدیکترین مقدار عدد صحیح اصلی است. پیاده
پارامترهای پارامتر شناور نقطه ی تجزیه کننده و انتزاعی در یک سلول -
هنگام بازیابی مقدار نقطه شناور از یک سلول، الگوی بیت
نباید تغییر کرد


همچنین ببینید: amx_ftoc




amx_Exec


- اجرای کد


نحو:
کد:
int amx Exec (AMX * amx، long * retval، int index)؛
amx ماشین انتزاعی که از آن برای فراخوانی یک تابع استفاده می شود.
بازالت مقدار برگشتی تابع نامیده می شود. این پارامتر ممکن است NULL باشد اگر شما ارزش بازگشتی را ندارید.
فهرست مطالب یک شاخص به "جدول تابع عمومی"؛ آن را نشان می دهد عملکرد را اجرا کنید. به amx_FindPublic formore اطلاعات مراجعه کنید. از AMX_EXEC_MAIN برای شروع اجرای تابع اصلی استفاده کنید و AMX_EXEC_CONT برای ادامه اجرای از "حالت خواب".


یادداشت ها: این تابع اسکریپت را اجرا می کند، با شروع از تابع مشخص شده. آی تی
تابع فراخوانی برای هر تابع بومی که کد را فراخوانی می کند
در AMX می سازد. amx_Exec فرض می کند که تمام توابع بومی هستند
با amx_Register به درستی مقداردهی شده است.


همچنین ببینید: amx_FindPublic ، amx_Register




amx_FindPublic


- نمایش شاخص عملکرد عمومی


نحو:
کد:
int AMX FindPublic (AMX * AMX، char * funcname، int * index)؛
amx ماشین انتزاعی
funcname نام توابع عمومی برای پیدا کردن.
فهرست مطالب پس از بازگشت، این پارامتر دارای شاخص عملکرد عمومی است.


همچنین ببینید: amx_Exec ، amx_FindNative ، amx_FindPubVar ، amx_GetPublic ،
amx_NumPublics




amx_ftoc


- بازیگران "شناور" به "سلول"


نحو:
کد:
[سلول] amx_ftoc ( شناور ) f)؛
f ارزش برای بازیابی از نوع "شناور" به "سلول".


بازگشت: همان الگوی بیتی، اما در حال حاضر به عنوان نوع سلولی.


یادداشت ها: این ماکرو یک نوع "شناور" را به نوع سلولی بدون تغییر تغییر می دهد
الگوی بیتی یک نوع نرمال در C / C ++ حافظه را تغییر می دهد
نمایندگی بیان به طوری که مقدار عددی آن در عدد صحیح باشد
فرمت، مقدار انتگرال (کوتاه) ارزش منطقی اولیه است.
پارامترهای پنهان و ماشین های انتزاعی نقطه های شناور در
یک سلول - هنگامی که ذخیره یک مقدار نقطه شناور در یک سلول، الگوی بیت
نباید تغییر کرد


همچنین ببینید: amx_ctof




amx_GetAddr


- آدرس AMX را حل کن


نحو:
کد:
int amx_GetAddr (AMX * amx، cell amx_addr، cell ** phys_addr)؛
amx ماشین انتزاعی
amx_addr آدرس مربوط به ماشین انتزاعی.
phys_addr اشاره گر به متغیری که حافظه آدرس سلول نشان داده شده را نگه می دارد. اگر پارامتر amx_addr یک آدرس معتبر درون ماشین انتزاعی نیست، phys_addr به NULL تنظیم می شود.


یادداشت ها: این تابع آدرس حافظه یک آدرس را در ab-
دستگاه stract یکی از این ویژگی ها در یک برنامه افزودنی استفاده می شود
ماژول، به شما اجازه می دهد تا به متغیرهای داخل انتزاعی دسترسی پیدا کنید
دستگاه.






amx_GetString


- یک رشته از ماشین انتزاعی را بازیابی کنید


نحو:
کد:
int amx_GetString ( char * dest، cell * source، int use_wchar، size_t size)؛
مقصد یک اشاره گر به یک آرایه شخصیتی از اندازه کافی برای نگه داشتن رشته منبع تبدیل شده.
منبع اشاره گر به رشته منبع. amx_GetAddr را برای تبدیل آدرس رشته در amx به آدرس physicaladm استفاده کنید.
use_wchar مقدار غیر صفر استدلال خرابی را به عنوان "شخصیت های گسترده" تعریف می کند - wchar_t، بدون توجه به نوع char it. این اجازه می دهد تا تابع برای ذخیره رشته یونیکد.
اندازه حداکثر تعداد کاراکترهای ذخیره شده در مقصد، از جمله صفر صفر است. اگر رشته در منبع بیشتر طول بکشد، رشته ای که در انتهای آن قرار دارد، محصور خواهد شد.


یادداشت ها: این تابع هر دو رشته بسته بندی شده و رشته های باز نشده را تبدیل می کند
از فرمت "پیاده" به فرمت "C". هنگام بازیابی
رشته Unpacked با استفاده از پارامتر use_wchar صفر، تابع
ممکن است کاراکترها را از کاراکترهای گسترده به 8 بیتی ASCII / ANSI مختل کند.


همچنین ببینید: amx_SetString




amx_push


- یک استدلال عددی "بر حسب ارزش"


نحو:
کد:
int amx_Push (AMX * amx، مقدار سلولی)؛
amx ماشین انتزاعی
ارزش ارزش برای انتقال به عملکرد عمومی.


یادداشت ها: هر پارامتر برای یک تابع عمومی باید به func-
قبل از فراخوانی amx_Exec اگر یک تابع عمومی چندین مرتبه داشته باشد
guments، این استدلال ها باید به ترتیب در جهت معکوس قرار بگیرند.


همچنین ببینید: amx_Exec ، amx_PushArray ، amx_PushString




amx_PushArray


- یک استدلال یا آرایه را "توسط مرجع"


نحو:
کد:
int amx_PushArray (AMX * amx، cell * amx_addr، cell ** phys_addr، arst cell cell []، int numcells)؛
amx ماشین انتزاعی
amx_addr آدرس سلول اختصاص داده شده به عنوان برنامه پیاده (که در ماشین انتزاعی اجرا می شود) می تواند به آن دسترسی داشته باشد، مورد نیاز برای انتشار بلوک حافظه. این پارامتر ممکن است NULL باشد.
phys_addr آدرس سلول برای برنامه های C / C ++ برای دسترسی. این پارامتر ممکن است NULL باشد.
آرایه آرایه ای از مقادیر برای انتقال به عملکرد عمومی. سلول تک سلولی که باید توسط مرجع به آن منتقل شود، به عنوان یک آرایه تک سلولی در نظر گرفته می شود.
numcells تعداد عناصر در آرایه.


یادداشت ها: هر پارامتر برای یک تابع عمومی باید به func-
قبل از فراخوانی amx_Exec اگر یک تابع عمومی چندین مرتبه داشته باشد
guments، این استدلال ها باید به ترتیب در جهت معکوس قرار بگیرند.
تابع حافظه را برای آرایه داخل "heap" از حافظه اختصاص می دهد
ماشین انتزاعی. این حافظه باید با amx_Release آزاد شود.
برای اطلاعات بیشتر در مورد پارامترهای amx_addr و amx_Allot به عملکرد تابع مراجعه کنید
phys_addr


همچنین ببینید: amx_Exec ، amx_Push ، amx_PushString ، amx_Release




amx_PushString


- آرگومان رشته را رد کنید


نحو:
کد:
int amx PushString (AMX * amx، cell * amx_addr، cell ** phys_addr، const char * string، int pack، int use_wchar)؛
amx ماشین انتزاعی
amx_addr آدرس سلول اختصاص داده شده به عنوان برنامه پیاده (که در ماشین انتزاعی اجرا می شود) می تواند به آن دسترسی داشته باشد، مورد نیاز برای انتشار بلوک حافظه. این پارامتر ممکن است NULL باشد.
phys_addr آدرس سلول برای برنامه های C / C ++ برای دسترسی. این پارامتر ممکن است NULL باشد.
رشته رشته برای انتقال به عملکرد عمومی.
بسته غیر صفر برای تبدیل رشته منبع به رشته بسته بندی شده در ماشین انتزاعی، صفر برای تبدیل رشته منبع به یک رشته سلولی.
use_wchar مقدار غیر صفر آرگومان رشته را به عنوان یک اشاره گر به "کاراکترهای گسترده" یعنی wchar_t، بدون توجه به نوع char آن، تفسیر می کند. این اجازه می دهد که تابع برای پذیرش رشته یونیکد باشد.


یادداشت ها: هر پارامتر برای یک تابع عمومی باید به func-
قبل از فراخوانی amx_Exec اگر یک تابع عمومی چندین مرتبه داشته باشد
guments، این استدلال ها باید به ترتیب در جهت معکوس قرار بگیرند.
تابع حافظه را برای آرایه داخل "heap" از حافظه اختصاص می دهد
ماشین انتزاعی. این حافظه باید با amx_Release آزاد شود.
برای اطلاعات بیشتر در مورد پارامترهای amx_addr و amx_Allot به عملکرد تابع مراجعه کنید
phys_addr
هنگامی که شما یک رشته یونیکد را منتقل می کنید و فرمت بسته بندی شده را درخواست می کنید
ماشین انتزاعی (یعنی هر دو بسته و use_wchar درست هستند)،
شخصیت ها به 8 بیت کوتاه می شوند.


همچنین نگاه کنید به: amx_Exec ، amx_Push ، amx_PushArray ، amx_Release
amx_SetString




amx_Register


- توابع بومی شناخته شوند


نحو:
کد:
int amx ثبت نام (AMX * AMX، AMX NATIVE INFO * لیست، شماره int )؛
amx ماشین انتزاعی
فهرست یک آرایه با ساختارهایی که هر ساختار دارای اشاره گر به نام یک تابع بومی و یک اشاره گر تابع است. این لیست به صورت اختیاری با ساختار نگهداری دو نشانگر NULL خاتمه می یابد.
عدد تعداد ساختارها در آرایه لیست، یا -1 اگر لیست به پایان می رسد با یک ساختار نگه داشتن دو اشاره گر NULL.


یادداشت ها: در مورد موفقیت، این تابع 0 (AMX_ERR_NONE) را باز می کند. اگر این func
یک کد خطا AMX_ERR_NOTFOUND، یک یا چند بومی را بازمی گرداند
توابع که توسط برنامه پیاده سازی استفاده می شود در
لیست ارائه شده. شما می توانید با amx_Register تماس بگیرید تا addi-
لیست های عملکرد
برای بررسی اینکه آیا تمام توابع بومی مورد استفاده در اسکریپت کامپایل شده است
ثبت شده است، با amx_Register با لیست پارامتر تماس بگیرید
تنظیم NULL این تماس هر توابع بومی جدید را ثبت نمی کند، اما
AMX_ERR_NOTFOUND اگر هنوز هیچ تابع بومی ثبت نشده باشد


همچنین ببینید: amx_NativeInfo




amx_Release


- فضای پشته ای رایگان در ماشین انتزاعی


نحو:
کد:
int AMX Release (AMX * amx، amx_addr سلول)؛
amx ماشین انتزاعی
amx_addr آدرس سلول اختصاص داده شده به عنوان برنامه پیاده (که در ماشین انتزاعی اجرا می شود) آن را می بیند. این مقدار توسط amx_Allot، amx_PushArray و amx_PushString بازگردانده شده است.


یادداشت ها: amx_Allot حافظه را بر روی پشته در جهت صعودی اختصاص می دهد
پشته رشد می کند). amx_Release تمام حافظه را از بالای حافظه آزاد میکند
مقدار پارامتر ورودی amx_addr. این یک تماس واحد است
amx_Release می توانید چندین فراخوانی را به amx_Allot آزاد کنید اگر شما از آن عبور می کنید
مقدار amx_addr از تخصیص اول.
amx_PushArray و amx_PushString از amx_Allot در داخل استفاده کنید، بنابراین
همان روش برای این توابع نیز کاربرد دارد.


همچنین ببینید: amx_Allot ، amx_PushArray ، amx_PushString




amx_SetString


- یک رشته در ماشین انتزاعی ذخیره کنید


نحو:
کد:
int amx SetString (cell * dest، char * source، int pack، int use_wchar، size_t size)؛
مقصد یک اشاره گر به یک آرایه شخصیتی در amx که رشته تبدیل آن ذخیره می شود. از amx_GetAddr برای تبدیل آدرس رشته در amx به آدرس فیزیکی استفاده کنید.
منبع اشاره گر به رشته منبع.
بسته غیر صفر برای تبدیل رشته منبع به یک بسته بندی شده
رشته در ماشین انتزاعی صفر برای تبدیل رشته منبع به یک رشته سلولی.
use_wchar مقدار غیر صفر استدلال منبع را به عنوان یک اشاره گر به "کاراکترهای گسترده" تفسیر می کند - wchar_t، صرف نظر از نوع char. این اجازه می دهد که تابع برای پذیرش رشته یونیکد باشد.
اندازه حداکثر تعداد سلول هایی که در محل قرار گیری ذخیره می شوند، از جمله صفر یا سلول متوقف می شود. اگر رشته در منبع طولانی تر از آن باشد که بتواند در تعداد سلول های موجود در مقصد قرار بگیرد، آن را کوتاه می کند.


یادداشت ها: هنگامی که یک رشته یونیکد را منتقل می کنید و فرمت بسته بندی شده را درخواست می کنید
ماشین انتزاعی (یعنی هر دو بسته و use_wchar درست هستند)،
شخصیت ها به 8 بیت کوتاه می شوند.


همچنین ببینید: amx_GetString




amx_StrLen


- طول رشته در کاراکترها را دریافت کنید


نحو:
کد:
int amx_StrLen ( const cell * cstring، int * length)؛
cstring رشته در ماشین انتزاعی.
طول این پارامتر طول رشته را پس از بازگشت نگه می دارد.


یادداشت ها: این تابع طول کاراکترهای رشته را تعیین نمی کند
از جمله شخصیت (یا سلول) پایان صفر است. یک رشته بسته بندی شده
اگر علامت باشد، سلول های کمتر از عدد آن را اشغال می کند.
اگر پارامتر cstring NULL باشد، پارامتر طول آن به
صفر (0) و تابع با یک کد خطا باز می شود.
برای تبدیل رشته های باز نشده به UTF-8، عملکرد amx_UTF8Len
ممکن است راحت تر باشد


همچنین ببینید: amx_GetAddr ، amx_GetString ، amx_SetString ، amx_StrParam ، amx_UTF8Len




amx_StrParam


- یک پارامتر رشته از یک ماشین انتزاعی دریافت کنید


نحو:
کد:
amx_StrParam ([AMX *] amx، int ] param، [ char *] نتیجه)؛
amx ماشین انتزاعی
پارامتر شماره پارامتر.
نتيجه یک متغیر که نتیجه را در بازگشت نگه می دارد.


یادداشت ها: این ماکرو یک بلوک حافظه (با alloca) و کپی را اختصاص می دهد
پارامتر رشته (به یک تابع بومی) در آن بلوک. صفحه 56 را ببینید
برای مثال از استفاده از این ماکرو.


همچنین ببینید: amx_GetAddr ، amx_GetString ، amx_StrLen


مثالهای عملکرد Amx


در تلاش برای اجتناب از دیوارهای متن بزرگ، تصمیم گرفتم به توضیح آنچه که من انجام می دهم، به جای کد کردن آن در موضوع، توضیحات اضافه کنم. احتمالا ایده خوبی است که مقاله wiki را به عنوان یک مرجع در هنگام خواندن نمونه ها باز کنید.


ثبت نام بومیان


هر تابع تکمیلی که PAWN ارائه می دهد باید ثبت شود تا ماشین انتزاعی بتواند از وجود آن آگاهی داشته باشد. بنابراین من فکر می کنم احتمالا یک ایده خوب برای شروع با amx_Regester است! خوشبختانه در واقع ما قبلا نمونه ای از ثبت یک بومی از بخش های قبلی خود را استفاده کردیم، بنابراین دوباره از این مثال استفاده خواهم کرد و برخی از نظرات را اضافه خواهم کرد.


پیاده روی کد:
// آرایه ای از توابع که می خواهیم با ماشین انتزاعی ثبت نام کنیم.
AMX_NATIVE_INFO PluginNatives [ ] =
{
// در اینجا ما اطلاعات توابع بومی ما را مشخص می کنیم و آرایه را با دو مقدار صفر خاتمه می دهیم.
{ "HelloWorld" ، HelloWorld }
{ 0 ، 0 }
} ؛


PLUGIN_EXPORT int PLUGIN_CALL AmxLoad ( AMX * amx )
{
// در اینجا ما بومیان را به دستگاه انتزاعی ثبت می کنیم. توجه داشته باشید که ما از -1 استفاده می کنیم. به طور معمول این تعداد باید باشد
// توابع ما ثبت نام می کنیم، اما از آنجایی که ما آرایه را با دو مقدار صفر خاتمه دادیم، می توانیم -1 را مشخص کنیم.
amx_Register بازگشت ( amx، PluginNatives، - 1 ) ؛
}
گرفتن یک رشته و طول آن


پیاده روی کد:
// این تابع نشان می دهد: چگونه یک رشته (و طول آن) را از PAWN دریافت کنید.
// بومی PAWN: بومی PrintPawnString (const str [])؛
سلول AMX_NATIVE_CALL PrintPawnString ( AMX * amx، cell * params )
{
int
len = null
ret = NULL؛


سلول * addr = NULL؛


// آدرس پارامتر رشته ما را دریافت کنید (str) و سپس طول آن را دریافت کنید
amx_GetAddr ( amx، params [ 1 ] ، & addr ) ؛
amx_StrLen ( addr، & len ) ؛


// اگر طول ورودی 0 نیست
اگر ( len )
{
// ما len را افزایش می دهیم زیرا ما می خواهیم زمانی که حافظه را اختصاص می دهیم برای کاراکتر خالی null استفاده کنیم.
// همچنین چون پارامتر اندازه GetString مقدار null chracter را می دهد، ما باید طول را مشخص کنیم
// از رشته + 1؛ در غیر این صورت رشته ما به صورت عددی خالی می شود (ما 1 کاراکتر را از دست می دهیم).
len ++ ؛


// حافظه را برای نگهداری رشته ما که گذراندیم (str) قرار دهیم و سپس رشته را با استفاده از حافظه اختصاص داده شده به آن "دریافت" کنیم تا آن را ذخیره کنیم.
char * text = new char [ len ] ؛
amx_GetString ( متن، addr، 0 ، len ) ؛


// استفاده از logprintf برای چاپ رشته (متن). ما از std :: cout استفاده نمیکنیم زیرا در سرور log وارد نشده است (فقط کنسول).
logprintf ( متن ) ؛


// حذف حافظه ما ...
حذف [ ] متن؛
}
بازگشت 1 ؛
}
راه دیگری برای گرفتن یک رشته


من تصمیم گرفتم این بخش را اضافه کنم، زیرا می دانم که مردم از سادگی آن وسوسه می شوند، و من فکر می کنم آنها باید از خطرات و مشکلات که می توانند از آن مطلع شوند، می دانند.


پیاده روی کد:
// این تابع نشان می دهد: یک روش جایگزین برای گرفتن رشته از پیاده و خطرات احتمالی که با آن می آیند.
// بومی PAWN: بومی PrintPawnString2 (const str [])؛
سلول AMX_NATIVE_CALL PrintPawnString2 ( AMX * amx، cell * params )
{
// این روش توصیه نمی شود زیرا ماکرو amx_StrParam از تابع alloca استفاده می کند که یک استاندارد در C یا C ++ نیست.
// استفاده از این روش با خطرات سرریز پشته همراه است (اگر حجم زیادی از حافظه را اختصاص دهید) و همچنین
// به شما می دهد خطر اشکالات (این تابع ماشین و کامپایلر وابسته است، بعضی از پیاده سازی گفته می شود bugged).


char * text = NULL؛
amx_StrParam ( amx، params [ 1 ] ، متن ) ؛


// بررسی کنید که متن null باشد
اگر ( متن = NULL )
{
// استفاده از logprintf برای چاپ رشته (متن). ما از std :: cout استفاده نمیکنیم زیرا در سرور log وارد نشده است (فقط کنسول).
logprintf ( متن ) ؛
}
بازگشت 1 ؛
}
نحوه تنظیم یک رشته


پیاده روی کد:
// این تابع نشان می دهد: چگونه یک رشته PAWN را تغییر دهید.
// بومی PAWN: بومی SetPawnString (str []، len = sizeof (str))؛
سلول AMX_NATIVE_CALL SetPawnString ( AMX * AMX، سلول * params )
{
const string message = "این یک رشته از C / ++ است" ؛
سلول * addr = NULL؛


// آدرس پارامتر رشته ما (str) را دریافت کنید و پیام ما را ذخیره کنید
amx_GetAddr ( amx، params [ 1 ] ، & addr ) ؛
amx_SetString ( addr، message.c_str ( ) ، 0 ، 0 ، params [ 2 ] ) ؛
بازگشت 1 ؛
}
ریخته گری و بازگشت شناور


پیاده روی کد:
// این تابع نشان می دهد: چگونه یک شناور را به یک شناور PAWN بفشارید و آن را بازگردانید.
// بومی PAWN: شناور بومی: ReturnPawnFloatVal ()؛
سلول AMX_NATIVE_CALL ReturnPawnFloatVal ( AMX * AMX، سلول * params )
{
// از آنجا که PAWN یک زبان غیر معمول است، همه چیز را به عنوان یک عدد صحیح 32 بیتی ذخیره می کند و به برچسب ها متصل می شود تا اطلاعات خاصی را اداره کند.
// تعداد عدد شناور استثنایی نیست. این یک اینترفیس 32 بیتی است، اما دارای یک برچسب شناور برای نشان دادن آن نبوده است
// مثل یک عدد صحیح منظم رفتار می شود. پس چگونه یک شناور را به یک عدد صحیح 32 بیتی (برای PAWN) تبدیل کنیم بدون اینکه داده ها را از دست داد؟
// پاسخ amx_ftoc ماکرو است!


// نوع amx_ftoc ماکرو یک شناور را به یک سلول در حالی که الگوی بیت خود را حفظ می کند (amx_ctof معکوس را انجام می دهد).
const شناور f = 22.624f؛
بازگشت amx_ftoc ( f ) ؛
}


پارامترهای عبور از مرجع


پیاده روی کد:
// این تابع نشان می دهد: چگونه می توان پارامترها را با مرجع انتقال داد.
// بومی PAWN: بومی SetPawnReferenceVars (& value1، & Float: value2)؛
سلول AMX_NATIVE_CALL SetPawnReferenceVars ( AMX * AMX، سلول * params )
{
const int val = 65 ؛
const شناور val2 = 84.54f؛


cell * addr [ 2 ] = { NULL، NULL } ؛


// آد
یکشنبه 19 خرداد 1398 - 06:09
نقل قول این ارسال در پاسخ گزارش این ارسال به یک مدیر

پاسخ ها


برای نمایش پاسخ جدید نیازی به رفرش صفحه نیست روی تازه سازی پاسخ ها کلیک کنید !



برای ارسال پاسخ ابتدا باید لوگین یا ثبت نام کنید.


پرش به انجمن :