# برنامه نویسی با محصولات مایکروسافت > برنامه نویسی مبتنی بر Microsoft .Net Framework > مقالات مرتبط با Microsoft .Net Framework >  مقدمه بسیار ساده‌ای بر توابع API در دات نت

## Abbas Arizi

برنامه نویسان ویژوال بیسیک تا قبل از ورود دات نت بسیار به توابع API وابسته بودند. به علت این که ویژوال بیسیک توابع و کلاسهای آماده بسیار کمی رو عرضه میکرد و حتی کنترلهای عمومی ویندوز رو هم به صورت بسیار ناقصی پشتیبانی می‌کرد، از این رو به وفور در برنامه‌ها از توابع API استفاده میشد.
اما در دات نت وضع بدین گونه نیست و شما می‌تونید از دریای کلاسها و توابع موجود در دات نت فریم ورک بهره بگیرید. بسیاری از اعمالی رو که در گذشته با مشقت فراوان و با استفاده از توابع API و به شکل نامطمئنی انجام می‌دادیم امروز به سادگی انجام پذیر است.
با این حال باز هم اگرچه بندرت ولی در مواردی ناچار به استفاده از این توابع خواهیم بود.
همون طور که می‌دونیم نخستین قدم برای استفاده از یک تابع API اعلام و وارد کردن اون تابع به برنامه است. در VB.NET دو راه برای اعلام یک تابع API وجود دارد. یکی استفاده از عبارت کلیدی Declare و دیگری استفاده از خصوصیت DllImport.
استفاده از Declare تا حد زیادی مشابه قبل می‌باشد لیکن برخی تفاوتهای جزئی نیز وجود دارد. 
یکی از این تفاوتها این است که در گذشته اعلام این توابع با دسترسی سراسری تنها در ماژولهای استاندارد (*.bas) ممکن بود ولی در دات نت می‌توان یک تابع API رو درون هر کلاسی و با دسترسی Public اعلام کرد.
تفاوت دیگری که می‌توان اشاره کرد این است که اگر احیانا خواستید یک تابع قدیمی رو به دات نت تبدیل کنید تمام متغیرهای از نوع Long رو باید به Integer تبدیل کنید. به عبارت دیگر در دات نتInteger  برابر Long در VB6.0 است.
در مورد استفاده از رشته‌ها و ساختارها تفاوتهای عمده‌ای وجود داره که اگر کسی مایل بود بعدا مختصری در مورد اون با هم صحبت خواهیم کرد. توی MSDN توضیحات کاملی در این زمینه وجود داره.
این یک مثال برای چگونگی اعلام یک تابع API در VB.NET است:
Declare Function MoveFile Lib "kernel32.dll" Alias "MoveFileA" &#40;ByVal lpExistingFileName As String, ByVal lpNewFileName As String&#41; As Integer 
روش دوم استفاده از DllImport است. این Attribute یک تابع در برنامه ما را به یک تابع داخل Dll منسوب می‌کند. برای بهره گیری از این خصوصیت باید فضای اسمی System.Runtime.InteropServices به صدر ماژول اضافه شود. این Attribute در کلاس DllImportAttribute قرار دارد.
شکل اعلام یک تابع با استفاده از این روش را در این مثال ملاحظه می‌کنیم.
&lt;DllImport&#40;"KERNEL32.DLL", EntryPoint &#58;= "MoveFileW", _
   SetLastError &#58;= True, CharSet &#58;= CharSet.Unicode, _
   ExactSpelling &#58;= True, _
   CallingConvention &#58;= CallingConvention.StdCall&#41;> _
Public Shared Function MoveFile&#40;src As String, dst As String&#41; As Boolean
    ' Leave function empty - DLLImport attribute forwards calls to MoveFile to
    ' MoveFileW in KERNEL32.DLL.
End Function

در #C:
&#91;DllImport&#40;"KERNEL32.DLL", EntryPoint = "MoveFileW",
SetLastError = true, CharSet = CharSet.Unicode,
ExactSpelling = true,
CallingConvention = CallingConvention.StdCall&#41;&#93; 
public static extern bool MoveFile&#40;string src,string dst&#41;;
بدنه تابع خالی می‌ماند و محتوای اون بوسیله DllImport فراخوانده میشود آرگومان اول که نام Dll رو معین میکنه و ارگومان دوم که نقطه ورودی تابع موردنظر رو تعیین میکنه آرگومانهای ضروری هستند و بقیه را میتوان درج نکرد. ولی بهتر است که از همین ترکیب پیروی شود.

به نظر من استفاده از روش دوم بهتره. چرا که روش دوم با اندک تغییراتی در سایر زبانهای دات نت هم کاربرد داره.

از این آدرس می‌تونید نرم‌افزاری رو دریافت کنید که اعلام اکثر توابع API رو به زبانهای مختلف در خودش داره.
http://www.activevb.de/rubriken/apiv...viewereng.html

----------


## Vahab

ممنون

----------


## sh

سلام

عباس دستت درد نکنه خیلی ممنون مقدمه خوبی بود

----------


## sh

دوستان دیگر اگر مطلب تکمیلی یا کتاب یا مثالهای عملی دارن لطف کنند و ارائه بدن

با تشکر

----------


## Abbas Arizi

ارسال ساختارها و کلاسها به عنوان پارامتر:

اگرچه در اکثر موارد فراخوانی Dll ها به شکل یکسانی صورت میگیرد ولی برخی استثنائات در این زمینه وجود دارد که به شرح برخی از آنها می پردازیم.
یکی از این استثنائات ارسال Structure ها می‌باشد.
بسیاری از توابع در کتابخانه‌های Unmanged یک کلاس یا ساختار را به عنوان آرگومان می‌پذیرند. هنگامی که از سیستم خواسته میشود که یک عضو کلاس یا Structure را به یک تابع ارسال کند، سیستم نیاز به یک سری اطلاعات اضافی برای فرمت آن ساختار دارد تا بتواند ترکیب و آرایش اصلی آن را حفظ نماید.

خصیصه StructLayout برای این منظور به کار می‌رود. این خصیصه کلاس یا ساختار موجود در برنامه ما را برای تابع احضار شده تفسیر میکند و آرایش و ترتیب قرارگرفتن اعضا را برای آن مشخص می‌کند.

ترکیب اعضا میتواند به سه شکل تعریف شود: اتوماتیک، ترتیبی و صریح.

در حالت اتوماتیک اعضا به صورت اتوماتیک در زمان اجرا مرتب میشوند.
تذکر: این گزینه را برای ارسال ساختار به توابع API به کار نبرید. در صورت انجام چنین کاری با یک خطا مواجه خواهید شد.

در حالت صریح ترتیب قرارگیری اعضا به صورت صریح مشخص میشود. یعنی ما به صراحت مشخص می‌کنیم که هر عضو باید در کجا قرار بگیرد. این کار از طریق خصلت FieldOffset برای هر فیلد انجام میشود.

در حالت ترتیبی اعضا با همان ترتیبی که در برنامه مشخص شده‌اند و بدون اینکه تغییری در آرایش آنها داده شود، ارسال میشوند.

مثال زیر چگونگی تعریف انواع Rect و Point و ارسال آنها به تابع PtInRect در User32.dll را نمایش میدهد. (این تابع بررسی می‌کند که یک نقطه داخل یک مستطیل قرار می‌گیرد یا خیر)
شکل اصلی این تابع به صورت زیر است:
BOOL PtInRect&#40;const RECT *lprc, POINT pt&#41;;
توجه داشته باشید که از آنجا که تابع انتظار یک اشاره گر به ساختار Rect را دارد، ساختار Rect را باید از طریق مرجع (ByRef) به تابع ارسال کنید.
Imports System.Runtime.InteropServices

&lt;StructLayout&#40;LayoutKind.Sequential&#41;  > Public Structure Point 'این ساختار به صورت ترتیبی پاس خواهد شد
    Public x As Integer
    Public y As Integer
End Structure

&lt;StructLayout&#40;LayoutKind.Explicit&#41;> Public Structure Rect	' این ساختار به صورت صریح پاس خواهد شد
    &lt;FieldOffset&#40;0&#41;> Public left As Integer
    &lt;FieldOffset&#40;4&#41;> Public top As Integer
    &lt;FieldOffset&#40;8&#41;> Public right As Integer
    &lt;FieldOffset&#40;12&#41;> Public bottom As Integer
End Structure

Class Win32API
    'اعلام تابع
    Declare Function PtInRect Lib "user32.dll" _
    &#40;ByRef lprc As Rect,ByVal pt As Point&#41; As Boolean
End Class

در #C:
using System.Runtime.InteropServices;

&#91;StructLayout&#40;LayoutKind.Sequential&#41;&#  93; public struct Point //این ساختار به صورت ترتیبی پاس خواهد شد 
&#123;
	public int x;
	public int y;
&#125;

&#91;StructLayout&#40;LayoutKind.Explicit&#41;&#93  ; public struct Rect   // این ساختار به صورت صریح پاس خواهد شد 
&#123;
	&#91;FieldOffset&#40;0&#41;&#93; public int left;
	&#91;FieldOffset&#40;4&#41;&#93; public int top;
	&#91;FieldOffset&#40;8&#41;&#93; public int right;
	&#91;FieldOffset&#40;12&#41;&#93; public int bottom;
&#125;
تعریف کلاسها هم تقریبا به همین صورت انجام میشود.

----------


## Vahab

بازم ممنون

امیدوارم ادامه پیدا کنه

----------


## sh

سلام

عباس جان دستت درد نکنه  :flower: 

امیدوارم تا افتادن صحیح دوزاری من کمی ادامه بدی 

با تشکر

----------


## Abbas Arizi

خواهش می‌کنم. قابلی نداره.
انشااله اگه دو زاری خودم توی بعضی مسائل کامل افتاد، باز هم ادامه میدم. :wink:
البته با توجه به اینکه از هفته آینده کلاس و مدرسه دوباره شروع میشه و اوقات بیکاری من به شدت کاهش پیدا می‌کنه :(  ممکنه وقوع این امر کمی به تاخیر بیفته.
به هر حال از دوستان دیگه اگر کسی اطلاعات خوبی داره که به درد بقیه می‌خوره دریغ نکنه.

----------


## sh

سلام

آقای عریضی اگر ممکنه یک مثال از استفاده از تابع RASDIAL در VB.NET برایم بزنید 

با تشکر

----------


## Abbas Arizi

عجب تابع خفنیه.
من نه تنها خودم نتونستم کدشو بنویسم، حتی کدهایی که از این ور و اون ور هم گیر آوردم هیچ کدوم کار نکرد. نه اونی که با VB نوشته شده بود نه اونی که با VB.NET نه سی شارپ  :گیج:   :گیج:  . فقط یه کد VC دل :heart:  بود که کار کرد.
شرمنده :oops:

حالا بازم پیگیرش هستم اگه بعدا به نتیجه‌ای رسیدم در جریان میذارمت.

----------


## sh

سلام

 (:D)  عباس جون پس خیال میکنی به خاطر چی شد که من سر بحث توابع API  رو باز کردم اولین مشکلی که داشتم با همین تابع بود 

انشالله که این بحث ادامه داشته باشه چون واقعا دات نت خیلی پیج و خم داره

نمیدونم آقای آذیش این تاپیک  رو دیده یا نه  :?: 


با تشکر

----------


## Abbas Arizi

درسته. توی دات نت استفاده از توابع API نسبت به قبل خیلی پیچیده تره و این کاملا طبیعیه. فراخوانی یک Unmanaged Code از یک Managed Code طبیعتا پیچیدگیهای خاص خودش رو داره.
ولی از یک طرف دیگه صرفنظر از زبان برنامه نویسی و پلتفرم هر کدام از توابع کاربرد و قواعد خاص خودشون رو دارن که باید به طور جداگانه مطالعه بشن و در اون مورد باید به مستندات خود این توابع مراجعه کرد.
در مورد این تابع هم همین طوره. هنوز کارکردهای اون یه مقدار مبهمه. چون من با VB که از این قید و بندها فارغه هم نتونستم کدی بنویسم که جواب درست بده.

----------


## sh

سلام

راستی آقای عریضی تونستی کاری بکنی با این تابع یا نه ؟

----------


## Abbas Arizi

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

----------


## sh

سلام

چیزی که الان نیاز دارم میخوام توی برنامه ای که دارم مینویسم کاربر بدون هیچ مداخله ای به اینترنت وصل بشه ولی در کل علاقه دارم یه چیزهائی برای استفاده از این تابع هم در سطح سرور و هم در سطح کلاینت بدونم که چطور مجوزها بررسی میشه و مثلا برنامه من در سرور بتونه تماس گیرنده رو شناسائی کنه و مجوز دسترسی بده

البته اگر کامپوننت هم گیر آوردی بد نیست ولی علاقه دارم از همون توابع API استفاده کنم توی چند تا فروم انگلیسی هم نوشتم ولی انگار هیچ کس نمیتونه :( 

راستی یه چیزی گیر آوردم ببین میتونی از توش کد VB.NET بیرون بکشی اگر تونستی مارو از یاد نبر :wink: 


با تشکرhttp://www.codeproject.com/useritems...mo/RasDemo.zip

----------


## Farhad.B.S

برای نیاز فعلیتون میتونید از این تابع استفاده کنید :

Declare Function InternetDial Lib "wininet.dll" &#40;ByVal hwndParent As Int32, ByVal lpszConnectoid As String, ByVal dwFlags As Int32, ByRef lpdwConnection As Int32, ByVal dwReserved As Int32&#41; As Int32


در باره RASDIAL هم میتونید یه نگاهی به این اکتیوایکس بندازید :
http://www.coolstf.com/docs/rasdial.html

یه مطلب دیگه اینکه اگه منظورتون نوشتن یه برنامه کلاینت/سرور در سطح TCP/IP هستش ، winsock هم گزینه خیلی خوبی هستش - هم امکان استفاده از اکتیوایکسش هست و هم امکان استفاده از ای پی آی هاش وجود داره.

----------


## Abbas Arizi

به نظر من بهتره از اسمبلیهای همین کد #C که داری استفاده کنی. کد خیلی خوب و جامعیه.

----------


## sh

سلام

دستت درد نکنه راستی کلا چه فرقی بین استفاده از این دی ال ال و تابه RAS  و Winsock  هست  وین سوک که تاجائی که من میدونم در ارتباط با شبکه ها و کنترل پورتها هست میشه یکم مسئله از حیث تفاوت دقیق مطرح کنید

راستی شما این کنترل را دارین ؟
با تشکر

----------


## Farhad.B.S

RAS یا Remote Access Service یه سرویس هستش که شامل دو بخش کلاینت و سرور میشه ، شما میتونید به عنوان یه RAS Client به یه RAS Server وصل بشید و از امکانات اون استفاده کنید ، به عنوان مثال وصل شدن شما به ISP تون و استفاده از امکانات اون (دریافت اطلاعات و مرور صفحات وب و...) معمولا از طریق همین سرویس هستش.
Winsock هم ای پی آی های در سطح ویندوز هست که از اون برای ارسال/دریافت اطلاعات استفاده میشه و البته در سطح TCP/IP ، یعنی شما باید اول یه ارتباط از لحاظ فیزیکی با یه جایی داشته باشی (به عنوان مثال استفاده با از RAS برای وصل شدن به یه آی اس پی) و بعد با استفاده از توابع Winsock به ادامه ارتباط بپردازی.

----------


## sh

سلام

من مشکلم با همون برنامه ای که گذاشتم تقریبا حل شده ولی هنوز اندر کف استفاده از تابع API مربوط به RAS توی دات نت هستم

----------


## HAMIDyekta

این فایل که خرابه

----------


## shadishadishadi

سلام
خسته نباشین 
با api جطوری میشه برنامه ای که تحت داس اجرا میشه رو اجرا کرد؟

----------


## mostafa20

با سلام 
من تازه به این جمع اضافه شدم امیدوارم که بتونم کمک کنم
من با Rasapi32.dll کار کردم و تونستم باهاش یه dialup بسازم
اگه دوست دارین واستون توضیح بدم که چه جوریه ولی خودم تو بعضی قسمت های بعد از اتصال مشکل بر خوردم کسی هست که چیزی بدونه
مثلا System Tray پس از اتصال و ConnectionStatus

----------


## PC2st

> مثلا System Tray پس از اتصال و ConnectionStatus


بصورت دستی، system try براش بگذار و Connection State هم با تابع InternetGetConnectedState از فایل wininet.dll قابل دسترسه.

----------


## VisualStudio

این هم یک نمونه کد فراخوانی توابع در VB.NET مرجع خود MSDN
امیدوارم این سورس کمکتون کنه و مفید واقع بشه

----------


## majidcomputer

از مطلبتون خیلی استفاده کردم

ممنون

----------


## sooran

سلام من میخواستم بدونم چطوری از توابع api برای پیدا کردن پرینترهای متصل به شبکه در #c استفاده کنم

----------


## firoozi90

System.Runtime.InteropServices

کسی می تونه در مورد این فضای نام توضیح کامل بده؟

----------

