مشکل:کدdllدر فراخوانی یک تابع در برنامه اصلی

mhabat

Member
با سلام.
من می خوام یک تابع رو که به زبان دیگه نوشته شده رو جدا گانه کامپایل کنم و ازش تو برنامه c++استفاده کنم.
برای این کار از دو قطعه کد زیر استفاده میکنند.اما من نتونستم درکش کنم.
اگر میشه توضیحاتی در موردشون بهم بدین.
کد:
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!");}}
کد:
#include <vcl.h>#include <windows.h>#pragma hdrstopextern "C"{__declspec(dllexport) void __stdcall VCL_Form(void);};#pragma argsusedint 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;}}
 

the_king

مدیرکل انجمن
با سلام.
من می خوام یک تابع رو که به زبان دیگه نوشته شده رو جدا گانه کامپایل کنم و ازش تو برنامه c++استفاده کنم.
برای این کار از دو قطعه کد زیر استفاده میکنند.اما من نتونستم درکش کنم.
اگر میشه توضیحاتی در موردشون بهم بدین.
کد ها مربوط به کلاس های Borland ای اند، C++ Builder

زمانی که روی دکمه ای در فرم کلیک شد :
کد:
void __fastcall TMainForm::ShowFormButtonClick(TObject *Sender)
{

برای دسترسی به یک تابع به اشاره گر نیاز داریم، نوع اشاره گر و پارامتر هایش باید مشخص شود
وگرنه نمی توانیم تابع را فراخوانی (اجرا) کنیم. اشاره گر به تابعی که به شیوه stdcall__ فراخوانی شده و
پارامتر ورودی و مقدار خروجی اش void است را از نوع PROC معرفی می کنیم :
کد:
	/* function pointer */
	typedef void(__stdcall *PROC)(void);

برای نگهداری اشاره گر تابع باید یک متغیر بسازیم، مثلا proc
کد:
	/* you also need a variable of type PROC */
	PROC proc;

برای دسترسی به تابع اول باید کتابخانه اش که تابع در آن قرار دارد را فراخوانی کنیم، در متغیر lib شماره Handle آن
کتابخانه بدست می آید :
کد:
	HMODULE lib = LoadLibrary("MyDLL.dll");

اگر شماره handle برابر 0 بود، کتابخانه به دلیلی قابل فراخوانی نیست، وگرنه ...
کد:
	if(lib != 0)
	{

اشاره گر تابع ای با نام VCL_Form (تابع اصلی فراخوانی یک فرم) را از درون کتابخانه بدست می آوریم :
کد:
		proc = (PROC)GetProcAddress(lib, "VCL_Form");

اگر اشاره گر NULL باشد، تابع مورد نظر پیدا نشده است، وگرنه...
کد:
		if(proc != NULL) 
		{

تابع مورد نظر را از طریق اشاره گر اش فراخوانی می کنیم :
کد:
			proc();
			/* call the function */
		}

اگر تابع مورد نظر پیدا نشد با پیغام خطا این مشکل را اعلام می کنیم :
کد:
		else 
		{
			ShowMessage("VCL_Host() cannot be found!");
		}

زمانی که کارمان با کتابخانه تمام شد باید آزاد اش کنیم :
کد:
		FreeLibrary(lib);
	}

اگر کتابخانه قابل فراخوانی کردن نبوده است با پیغام خطا اعلام می کنیم :
کد:
	else
	{
		ShowMessage("LoadLibrary failed!");
	}

include های مورد نیاز :
کد:
#include <vcl.h>
#include <windows.h>

تعریف تابع VCL_Form که باید از بیرون از کتابخانه قابل فراخوانی باشد (export شود)
کد:
#pragma hdrstopextern "C"
{
	__declspec(dllexport) void __stdcall VCL_Form(void);
};

زمانی که یک کتابخانه فراخوانی می شود تابع DllEntryPoint اجرا می گردد. اگر فراخوانی موفقیت آمیز باشد باید
مقدار True (یک مقدار غیر صفر) برگردانده شود :
کد:
#pragma argsusedint WINAPI DllEntryPoint(HINSTANCE hinst,unsigned long reason, void* lpReserved)
{
	return 1;
}

پیاده سازی تابع VCL_Form
کد:
void __stdcall VCL_Form(void)
{

یک فرم جدید از نوع TForm در برنامه Application ایجاد می گردد :
کد:
	TForm* f = new TForm(Application);

اگر در ادامه خطایی رخ داد آنرا مدیریت خواهیم کرد :
کد:
	try
	{

عنوان فرم را مشخص کرده و سپس نمایش اش می دهیم :
کد:
		f->Caption = "VCL Form in a C++‎‎ DLL";
		f->ShowModal();
	}

چه خطا رخ داده باشد و چه رخ نداده باشد فرم را حذف کرده و حافظه اش را آزاد می کنیم :
کد:
	__finally
	{
		delete f;
	}
 

جدیدترین ارسال ها

بالا