PDA

View Full Version : سوال:فراخوانی یک فایل(تابع)درون برنامه اصلی



mhabat
جمعه 11 فروردین 1391, 17:16 عصر
با سلام.من یک تابع نوشتم که می خوام اونو تو یک فایل دیگه کامپایل کنم و ازش تو برنامه اصلی استفاده کنم.
برای این کار چه کار باید کرد؟
باید تابع رو به صورت DLLکامپایل کنم؟کامپایل این فایل ها یا کامپایر های CPPانجام پذیر؟
برای اینکه اون تابع رو تو برنامه اصلی فراخوانیم بایدDLLنویسی بلد باشیم؟
اگه نیاز به dllنویسی زیادی نداه اگه میشه دستورشو بگین.
این اولین پست من دراین انجمن.جای درستی پست دادم؟اگه نه لطفا بگین.
خیلی ممنون
بــــدرود

Ananas
شنبه 12 فروردین 1391, 04:48 صبح
سلام دوست عزیز خوش اومدی.
نه دیگه dll نمیخواد. اون تابعی که نوشتی تو یک فایلی ذخیره کردی مثلا MyHeader.h ، حالا این فایل رو تو پوشه اصلی برنامت کپی کن بعد تو برنامه اصلی قبل از فراخونی تابع اونو با عبارت "include "MyHeader.h# به پروژه اضافه کن به این شکل :

#include "MyHeader.h"

maine
{

}

بعد میتونی تابع رو فراخونی کنی.

mhabat
شنبه 12 فروردین 1391, 12:15 عصر
سلام.ممنون از پاسخ خوبتون.بله این کاری رو که میگین رو من خودم انجام دادم.
اما من یک تایع به زبان دیگه یی نوشتم بعد می خوام ازش تو برنامه اصلی استفاده کنم.
برای این کار دیگه نمیشه includeکرد.
خیلی ممنون
بدرود

BORHAN TEC
شنبه 12 فروردین 1391, 12:44 عصر
برای استفاده از dll ها در C++‎‎‎‎‎‎‎‎ Builder روشهای مختلفی وجود داره. در زیر یک نمونه کد از بارگزاری dll ها به صورت dynamic موجود هست که در کتاب Inside Delphi 2006 آمده:


void __fastcall TMainForm::ShowFormButtonClick(TObject *Sender)
{
/* function pointer */
typedef void(__stdcall *PROC)(void);
/* you also need a variable of type PROC */
PROC proc;

HMODULE lib = LoadLibrary("MyDLL.dll");
if(lib != 0)
{
proc = (PROC)GetProcAddress(lib, "VCL_Form");
if(proc != NULL) {
proc(); /* call the function */
} else {
ShowMessage("VCL_Host() cannot be found!");
}

FreeLibrary(lib);
}
else
{
ShowMessage("LoadLibrary failed!");
}
}


این هم کدمربوط به DLL مربوطه است:
#include <vcl.h>
#include <windows.h>
#pragma hdrstop

extern "C"
{
__declspec(dllexport) void __stdcall VCL_Form(void);

};

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst,
unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------

void __stdcall VCL_Form(void)
{
TForm* f = new TForm(Application);
try
{
f->Caption = "VCL Form in a C++‎ DLL";
f->ShowModal();
}
__finally
{
delete f;
}
}


شدیداً پیشنهاد میکنم که اگر آشنایی زیادی با C++ Builder ندارید کتاب Inside Delphi 2006 رو بخوانید چون این یکی از سریعترین راههای یادگیری Delphi و C++ Builder در کنار یکدیگر است. :چشمک:

mhabat
شنبه 12 فروردین 1391, 14:14 عصر
سلام.تشکـــر از پاسختون.اگه میشه یه توضیحی در مورد کد های بالا میدین.
این کتاب Inside Delphi 2006زبانش انگلیسه منم بلد نیستم.زبان فارسی کتاب خوب نداره؟
من الان باturboو هم visual C++کار می کنم در کنار این ها دلفی هم میشه کار کرد دیگه؟فرق turboباbuilderزیاده؟
من c++کار کردم اما نتونستم از کد های بالا سر در بیارم.
ببخشید.
خیلی ممنون
بدرود

BORHAN TEC
شنبه 12 فروردین 1391, 16:29 عصر
زبان فارسی کتاب خوب نداره؟متاسفانه خیر

من الان باturboو هم visual C++‎‎‎‎‎کار می کنم در کنار این ها دلفی هم میشه کار کرد دیگه؟در کنار C++‎‎‎‎ Builder می توانید از دلفی هم استفاده کنید. البته اگر حالات استاندار را رعایت کنید و تجربه نسبتاً بالایی داشته باشید تقریباً می توان گفت که در کنار تمامی زبان ها می توانید از دلفی هم استفاده کنید، حتی برنامه های تحت دات نت و غیره ...! اما در مورد دلفی و C++ Builder باید بگویم که سازگاری آنها با هم بسیار بالاست به گونه ای که هر دوی آنها در محیط RAD Studio یکپارچه شده اند و از طرفی هم حتی می توانید به صورت مستقیم از کدهای دلفی در C++‎‎ Builder استفاده کنید و حتی تقریباً تمامی کامپوننت های دلفی در C++‎‎ Builder هم قابل استفاده اند. توجه داشته باشید که دلفی و C++‎‎ Builder بسیار به هم شبیه هستند و اشخاصی که با یکی از این دو آشنا باشند به را حتی می توانند از آن یکی هم استفاده کنند. در اینجا تقریباً تنها تفاوتی که وجود دارد این است که Syntax مربوط به دلفی از Object Pascal و Syntax مربوط به C++‎‎ Builder هم از زبان C++‎‎ مشتق شده است(یا بهتر است که بگویم زبان مربوط به C++‎‎ Builder همان C++‎‎ استاندارد است).

فرق turboباbuilderزیاده؟بله، از زمین تا آسمون. turbo یک محیط بسیار قدیمی و منسوخ شده است در صورتی که C++‎‎‎‎ Builder که جدیدترین نسخه آن XE2 است (به عبارتی نسخه 20102) یک محیط کاملاً جدید است که از برنامه های GUI هم به بهترین شکل ممکن پشتیبانی می کند. قابلیت های این محیط بسیار زیاد است که توضیح در مورد آنها از حوصله این بحث خارج است.

من C++‎‎‎‎‎کار کردم اما نتونستم از کد های بالا سر در بیارم.در زیر سعی می کنم که قسمت های مهم کد بالا رو توضیح بدم.

در مورد کد اول:
typedef void(__stdcall *PROC)(void);
ساختار مربوط به تابع export شده از dll را تعریف می کند تا بتوانیم از آن استفاده کنیم.

PROC proc;
یک متغیر از همان ساختار بالا را تعریف می کند.

HMODULE lib = LoadLibrary("MyDLL.dll");
dll را لود کرده و یک هندل از ماجول مربوطه را درون متغیر lib میریزد. اگر مقدار صفر در lib قرار گیرد یعنی این عمل موفقیت آمیز نبوده است. این مسئله دلایل مختلفی دارد: به عنوان مثال ممکن است که این کتابخانه اصلاً در سیستم وجود نداشته باشد.

proc = (PROC)GetProcAddress(lib, "VCL_Form");
آدرس مربوط به تابع VCL_Form را از داخل ماجول مربوطه بدست آورده و با یک typecasting مناسب آن را به درون متغیر proc میریزد. اگر در داخل proc مقدار NULL قرار بگیرد یعنی نتوانسته ایم به آدرس تابع مربوطه دست پیدا کنیم و عملیات موفق آمیز نبوده است.

proc();
اگر تا به اینجای کار عملیات موفق آمیز بوده باشد با این کد تابع مربوطه که در درون dll قرار داشت فراخوانی میشود.

FreeLibrary(lib);
dll مربوطه را از حافظه آزاد سازی می کند.

در مورد کد دوم:
__declspec(dllexport) void __stdcall VCL_Form(void);
از کد بالا برای export کردن تابع VCL_Form از درون dll استفاده شده است.

int WINAPI DllEntryPoint(HINSTANCE hinst,
unsigned long reason, void* lpReserved)
{
return 1;
}
این تابع در واقع نقطه ورودی dll می باشدکه به صورت خودکار توسط سیستم فراخوانی می شود و از آن به منظورهای مختلفی می توان استفاده کرد. مثلاً این که می خواهید در خود dll بفهمید که چند ترد مختلف در حال حاضر در حال استفاده از dll هستند و ... که این موضوع جزو مسائل حرفه ای تر C++‎‎‎‎ Builder میباشد که اگر بعداً به آن نیاز پیدا کردید بگویید تا بیشتر توضیح بدهیم.

void __stdcall VCL_Form(void)
{
TForm* f = new TForm(Application);
try
{
f->Caption = "VCL Form in a C++‎‎‎‎‎‎ DLL";
f->ShowModal();
}
__finally
{
delete f;
}
}
این قسمت هم چیز خاصی ندارد و در واقع تعریف بدنه تابعی است که می خواهیم آنرا export کنیم.


این کتاب Inside Delphi 2006زبانش انگلیسه منم بلد نیستم.به عنوان یک نصیحت برادرانه باید بدانید که در دنیای کامپیوتر آشنا نبودن به زبان انگلیسی مثل داشتن ماشینی بدون لاستیک است و باید تلاش کنید که زبان انگلیسی خودتون رو کمی تقویت کنید. بر خلاف آنچه که بسیاری تصور می کنند باید بگویم که این کار زیاد هم سخت نیست!:چشمک:

موفق باشید... :قلب: