PDA

View Full Version : حرفه ای: استفاده از کلاس تعریف شده در DLL



Collector
دوشنبه 26 فروردین 1392, 10:06 صبح
سلام
من میخوام از کلاسی که در فایل DLL نوشتم استفاده کنم چطوری میتونم به کلاس دسترسی داشته باشم
به تابع TestFunc که جزو کلاس نیست با این کد دسترسی دارم
typedef int (WINAPI*cfunc)();
cfunc TestFunc;
HINSTANCE hLib = LoadLibrary(TEXT("createdllC.dll"));
TestFunc = GetProcAddress((HMODULE)hLib, "TestFunc");
cout<<"Number :"<<TestFunc()<<endl;
if(hLib == NULL)
cout<<"Error: Unable to Load Library!"<<endl;
FreeLibrary((HMODULE)hLib);

فایل هدر:
#include "iostream"

using namespace std;

class testDLL
{
public:
__declspec(dllexport) string Path_File();
};

فایل CPP:
#include <iostream>
#include <conio.h>
#include <windows.h>
//=====
#include "testDLL.h"

using namespace std;

extern "C" __declspec(dllexport) int TestFunc()
{
return 1002;
}

string testDLL::Path_File()
{
string Path = "C:\\WINDOWS\\File\\";
return Path;
}

فایل Def:
LIBRARY "createdllC"
DESCRIPTION "An example DLL for interfacing with C++‎"

EXPORTS
TestFunc @1
Path_File @1

UfnCod3r
دوشنبه 26 فروردین 1392, 13:21 عصر
اون حالت لود کردن ران تایم برای کارای دیگست .
الان شما اول باید یه پروژه از نوع DLL بزنی .
بعد یه هدر و یه فایل سورس درست کن .
اینا رو تو هدر بنویس

#ifdef BUILD_DLL
#define DLLDECL __declspec(dllexport)
#else
#define DLLDECL __declspec(dllimport)
#endif

class DLLDECL MyClass
{
public:
void func1();
static void Func2();
}

برای کامپایل این دی ال ال صفت کلاس یا توابع و .. یاید dllexport باشه و برای استفاده در جاهای دیگه هم باید dllimport
برای این کار به قسمت تنظیمات پروژه برو و بعد قسمت preprocessor
و بعد اینو بنویس BUILD_DLL
:لبخندساده:

Collector
دوشنبه 26 فروردین 1392, 17:20 عصر
من میخوام از دینامیک استفاده کنم (حین اجرای برنامه میخاوم DLL آپدیت بشه)
موقع فراخوانی چطوری باید فراخوانی کنم از فایل اجرایی؟

این برنامه (http://edn.embarcadero.com/article/20165) را اجرا کردم ولی جواب نگرفتم

UfnCod3r
دوشنبه 26 فروردین 1392, 18:47 عصر
باید یه دی ال ال رابط بین اینا بنویسی که از توابع virtual استفاده کنی . مثل همون لینک
بعد دی ال ال های دیگه که می نویسی باید از اون دی ال ال رابط استفاده کنی .
مثل این

//////////////////interface.dll//////////////////////
#ifdef BUILD_DLL
#define DECL __declspec(dllexport)
#else
#define DECL __declspec(dllemport)
#endif

class DECL CBase
{
virtual void func() = 0;
}



/////////////////////dll1/////////////////////////////
#include "Interface.h"
#ifdef BUILD_DLL
#define DECL __declspec(dllexport)
#else
#define DECL __declspec(dllemport)
#endif

class DECL CClass1 : public CBase
{
void func();
}
//.cpp
void CClass1::func()
{
printf("called!!\n");
}

DECL extern "C" void* GetInstance()
{
return new CClass1;
}



/////////////////////exe///////////////////////////////
#include "Interface.h"

int main(int argc, char** argv)
{
typedef void*(FuncNS)();
HMODULE hLib = LoadLibrary("dll1.dll");
FuncNS getNewIns = (FuncNS)GetProcAddress(hLib, "GetInstance");
Interface* ins = (Interface*)getNewIns();
ins->func();
FreeLibrary((HMODULE)hLib);
}

Collector
سه شنبه 27 فروردین 1392, 18:12 عصر
میشه کاریش کرد فقط یک DLL باشه دیگه نمیخوام موقع آپدیت دو تا فایل را دانلود کنم
با تشکر

Collector
پنج شنبه 19 اردیبهشت 1392, 16:07 عصر
سلام
هنوزه که مشکلم حل نشده
این سورس DLL در vs هست اگر امکان داره بگید چه تغییراتی باید در DLL و با گه کدی از تابع Path_File که عضو کلاس Path هست استفاده کنم

Collector
پنج شنبه 19 اردیبهشت 1392, 17:36 عصر
این کد (http://www.mingw.org/wiki/Exporting_a_class_from_a_DLL_for_multiple_instanti ations) را هم تست کردم داخل فایل هدر از خط یکی مانده به آخر این خطا را میگیره


syntax error : '__declspec(dllexport)'

Collector
پنج شنبه 19 اردیبهشت 1392, 18:00 عصر
این کد (http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL) هم هست ولی من چطوری میتونم خروجی را نمایش بدم با این کد که آدرس حافظه را نمایش میده


std::cout<<pXyz->Foo(42);

UfnCod3r
پنج شنبه 19 اردیبهشت 1392, 18:05 عصر
باید ی رابط بینشون باشه
اینی ک گذاشتی اصلا همه چیزت اشتباه بود شما این کدی ک من گذاشتمو نگا کن و مثل اون عمل کن
شما اصلا ی چیز دیگه نوشتی
می تونی عوض توابع virtual از اشاره گر ب تابع هم استفاده کنی
اینم ی مثال دیگه

//////////////////interface.dll//////////////////////
//.h
#ifdef BUILD_DLL
#define DECL __declspec(dllexport)
#else
#define DECL __declspec(dllemport)
#endif

DECL void RegFunc(void(*pFunc)());
DECL void CallFunc();

//.cpp
void(*gPFunc)() = 0;
void RegFunc(void(*pFunc)())
{
gPFunc = pFunc;
}
void CallFunc()
{
gPFunc();
}

/////////////////////dll1/////////////////////////////
//.cpp
#include "Interface.h"

void PrintHello()
{
printf("hello\n");
}
__declspec(dllexport) extern "C" void StartDLL()
{
RegFunc(PrintHello);
}



/////////////////////exe///////////////////////////////
//.cpp
#include "Interface.h"

int main(int argc, char** argv)
{
typedef void(FuncSD)();
HMODULE hLib = LoadLibrary("dll1.dll");
FuncSD ff = (FuncSD)GetProcAddress(hLib, "StartDLL");
ff();
CallFunc();
FreeLibrary(hLib);
}

Collector
پنج شنبه 19 اردیبهشت 1392, 18:16 عصر
توی کدی که توی پست چهار گذاشتید 2 تا DLL باید باشه که این خوب نیست نمیشه توی یک DLL خلاصه بشه؟
در پست آخرتون هم که از کلاس استفاده نشده(اگر تابع خالی باشه که راحت میشه استفاده کرد)

Collector
پنج شنبه 19 اردیبهشت 1392, 18:25 عصر
الان این پروژه پست 4 هست که باز مشکل داره (البته داخل یک DLL نوشتم)

UfnCod3r
پنج شنبه 19 اردیبهشت 1392, 19:12 عصر
میشه ولی بستگی داره بازم ی رابط می خواد ولی دی ال ا ل نیاز نیست فقط ی هدر لازمه
یکم سخت میشه شما همون دو تا دی ال الی کار کن
تو نت مثال های زیادی هست

Collector
جمعه 27 اردیبهشت 1392, 17:33 عصر
سلام
مشکل با این کد (http://eli.thegreenplace.net/2011/09/16/exporting-c-classes-from-a-dll/) حل شد