Хочу создать файл Dll. Делаю так File->New->Other->Dll wizard
Там забиваю:
#include <windows.h>
extern "C" __declspec(dllexport)
double AddNumbers(double a, double b)
{
return a + b;
}
Что я только что сделал:
Открыл Билдер, File -> New -> Other -> Dynamic Link Library...
В диалоговом окне отключил все примочки VCL и Multi-Threading-а, сделал язык не С++, а С.
Открывается редактор:
#include <windows.h>
// Тут много букв - это пока неважно ...
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
#include <windows.h>
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif
double DLL_EXPORT AddNumbers(double a, double b)
{
return a + b;
}
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
Сделал так. Получил .dll.
Теперь в другом проекте.
#include <windows.h>
#include <stdio.h>
#define BUILD_DLL
//...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
typedef int(*importFunction)(int, int);
importFunction addNumbers;
int result;
HINSTANCE hinstLib = LoadLibrary("Project2.dll");
addNumbers = (importFunction)GetProcAddress(hinstLib, "AddNumbers");
result = addNumbers(1, 2);
Edit1->Text=IntToStr(result);
FreeLibrary(hinstLib);
}
DLL:
#include <windows.h>
double __declspec(dllexport) CALLBACK AddNumbers(double a, double b)
{
return a + b;
}
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
Все работает...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
typedef double(CALLBACK *importFunction)(double, double);
importFunction addNumbers;
int result;
HINSTANCE hinstLib = LoadLibrary("Project2.dll");
addNumbers = (importFunction)GetProcAddress(hinstLib, "AddNumbers");
result = addNumbers(1, 2);
Edit1->Text=IntToStr(result);
FreeLibrary(hinstLib);
}
Спсибо разобрался...
А если необходимо создать .dll в котором описаны методы класса...это как сделать?...
Надо ли изменять или создавать файл .h или что то похожее?..
Ничего не надо ни изменять ни создавать заново. Один и тот же H-файл может использоваться и для DLL, и для использующей ее программы. Только в DLL класс должен описываться как
class __declspec (dllexport) MyClass {
...
};
class __declspec (dllimport) MyClass {(элементарно делается с использованием #ifdef)
...
};
Пишу в файле который хочу чтобы был .dll с описанием методов класса.
// #include "A.h"
// class __declspec(dllimport) A; Что то из этого нужно?
extern "C" __declspec(dllexport)
void A::setC(int anC)
{
C=anC;
};
class __declspec(dllexport) A
{
public:
virtual void setC(int anC);
private:
int C;
};
Используя LoadLibrary ты замучаешься работать с классом из DLL. Вот тут лежит пример, посмотри:
http://www.codeproject.com/dll/classesexportedusingLL.asp
Гораздо проще работать с LIB-файлом. Для этого случая:
Подключаемый к DLL-проекту header:
class __declspec(dllexport) MyClass {
public:
MyClass(int);
virtual void setConsumerID(int);
int getConsumerID();
private:
int ConsumerID;
};
#include <windows.h>
#include "MyClass.h"
MyClass::MyClass(int value) {
ConsumerID = value;
}
void MyClass::setConsumerID(int value) {
ConsumerID = value;
}
int MyClass::getConsumerID() {
return ConsumerID;
}
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
MyClass my(10);
ShowMessage(IntToStr(my.getConsumerID()));
}
Сделал как ты написал. Спасибо работает. Но является ли это динамической загрузкой.
Исходя из примера пишу HMODULE hMod = LoadLibrary ("ProjectDll.dll") выдаёт ошибку.
Как её загрузить?
Пишу так:
{
typedef int (*importFunction)();
importFunction getConsumer;
HMODULE hMod = LoadLibrary ("ProjectDll.dll");//<--Или .lib?
getConsumer = (importFunction)GetProcAddress(hMod, "getConsumer");
MyClass my(10);
ShowMessage(IntToStr(my.getConsumerID()));
}
Вообще-то с LoadLibrary проблем быть не должно. У меня по крайней мере оно работает... А вот getConsumer - нулевой...
А это:
...
MyClass my(10);
...
http://forum.sources.ru/index.php?showtopic=42324&view=findpost&p=1468727 есть довольно подробное объяснение процесса (и альтернативы тоже)...
У меня третьим WinRar-ом свободно открылся...
А что там внутри у тебя не открывается? BPR - файлы проекта, открывай их и компилируй DLL-ку и саму программу...
Всё!!! ...у меня получилось...спасибо огромное...только вопрос один:
откуда вообще в процессе работы программы берёться то что необходимо обратиться к файлу
КлассНаследник.cpp ведь ни один файл его не включает в себя?..
typedef IMyCls * (__declspec(dllimport) FCreate(int Size));
...
class TfrmTestDll : public TForm {
...
FCreate * Create; // <--- это что по-твоему?
...
};
typedef IMyCls * (__declspec(dllimport) FCreate(int Size));
...
class TfrmTestDll : public TForm {
...
FCreate * Create; // <--- это что по-твоему?
...
};
Если честно - я не понял, что тебя смущает вообще... У тебя же в DLL создается экземпляр класса-наследника (т.е., MyCls). То, что указатель на него приводится к указателю на предка (то есть, к IMyCls *) - это тебя смущает?
Как это "не подключается?"
А в DBTEST.BPR что такое:
То есть таким образом он подключаеться. Буду знать.
Вот прочитал help на который ты давал ссылку...
откуда взяться файлу .def?..самому создать?..
И как узнать как назвал компилятор мою функцию?..
LIBRARY PROJECT3.DLL
EXPORTS
@MyClass@$bctr$qi @1 ; MyClass::MyClass(int)
@MyClass@getConsumerID$qv @3 ; MyClass::getConsumerID()
@MyClass@setConsumerID$qi @2 ; MyClass::setConsumerID(int)
@std@nothrow @5 ; std::nothrow
___CPPdebugHook @4 ; ___CPPdebugHook
Это через DOS в смысле?
Он ругаеться на то что Program Files отдельно написано...
Это через Start -> Run -> CMD ...
то, что до знака ">" - это системное приглашение, тебе надо войти в папку \BIN... А там уже напечатать то, что выделено красным...
Возьми в кавычки... То есть,
CD "диск_на_котором_у_тебя_билдер:\Program Files\Borland\ну_и_дальше_путь_к_папке" должно дать то же результат...
Получил. Так теперь можно задать имя функции своё?
Понянто...спасибо...