Позднее связываение с DLL
char * CodeDec(char *, char)
Хочу динамически подключить эту DLL:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HINSTANCE inst = LoadLibrary("MyDLL.dll");
char * (__stdcall *MyF)(char *, char);
MyF = (char * (__stdcall *)(char*, char)) GetProcAddress(inst, "CodeDec");
Edit1->Text =MyF(Edit1->Text.c_str(), 'A');
FreeLibrary(inst);
}
Ошибка: Программа выполнила недопустимую операцию и будет закрыта (и хохма такая: Если ошибка будет повторяться обратиться к разработчику)
[Программа вызвала сбой при обращении к странице памяти в модуле KERNEL32.DLL и т.д.]
Пошагово компилирую: inst присваивает адрес, а указателю MyF присваивает NULL.
Помогите если знаете в чем дело. У меня Builder5, Windows 98.
У меня есть DLL c одной функцией
char * CodeDec(char *, char)
Хочу динамически подключить эту DLL:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HINSTANCE inst = LoadLibrary("MyDLL.dll");
char * (__stdcall *MyF)(char *, char);
MyF = (char * (__stdcall *)(char*, char)) GetProcAddress(inst, "CodeDec");
Edit1->Text =MyF(Edit1->Text.c_str(), 'A');
FreeLibrary(inst);
}
Ошибка: Программа выполнила недопустимую операцию и будет закрыта (и хохма такая: Если ошибка будет повторяться обратиться к разработчику)
[Программа вызвала сбой при обращении к странице памяти в модуле KERNEL32.DLL и т.д.]
Пошагово компилирую: inst присваивает адрес, а указателю MyF присваивает NULL.
Помогите если знаете в чем дело. У меня Builder5, Windows 98.
Скорее всего надо писать вот так:
MyF = (char * (__stdcall *)(char*, char)) GetProcAddress(inst, "_CodeDec");
как объявлена функция (CodeDec) в dll?
Скорее всего надо писать вот так:
MyF = (char * (__stdcall *)(char*, char)) GetProcAddress(inst, "_CodeDec");
как объявлена функция (CodeDec) в dll?
Попробовал не помогло.
В DLL функция обьявляется в заголовочном файле:
#ifndef _MYDLL_H
#define _MYDLL_H
#ifdef __DLL__
#define DLL_EI __declspec(dllexport)
#else
#define DLL_EI __declspec(dllimport)
#endif
char * DLL_EI CodeDec(char *, char);
// DLL_EI char * CodeDec(char*, char); -
// тоже пробовал
#endif
и заголовочный файл подключаю к файлу .cpp где реализована функция. В таблице экпорта посмотрел моя функция есть.
Попробовал не помогло.
В DLL функция обьявляется в заголовочном файле:
#ifndef _MYDLL_H
#define _MYDLL_H
#ifdef __DLL__
#define DLL_EI __declspec(dllexport)
#else
#define DLL_EI __declspec(dllimport)
#endif
char * DLL_EI CodeDec(char *, char);
// DLL_EI char * CodeDec(char*, char); -
// тоже пробовал
#endif
и заголовочный файл подключаю к файлу .cpp где реализована функция. В таблице экпорта посмотрел моя функция есть.
1)
Ну я бы сделал так:
#ifndef _MYDLL_H
#define _MYDLL_H
extern "C" __declspec(dllexport) char * CodeDec(char *, char);
#endif
2) Вызывал бы так:
typedef char* (__import *CD)(char*, char);
CD CodeDec;
HINSTANCE Dll;
Dll = LoadLibrary("MyDll");
if(Dll != NULL)
{
CodeDec = (CD)GetProcAddress(Dll,"_CodeDec");
Edit1->Text = CodeDec(Edit1->Text.c_str(), 'A');
FreeLibrary(Dll);
}
Называется это динамической компоновкой а не поздним связыванием.
И кстати ЗЫ:
Называется это динамической компоновкой а не поздним связыванием.
Спасибо, получилось по твоему способу, хотя я и не понял почему у меня функция не импортируется.
Если нетрудно объясни, что такое позднее связывание, а то я почему то думал, что динамическая компановка это одно и тоже. Ты уж прости меня ламу, за вопросы такие.
Спасибо, получилось по твоему способу, хотя я и не понял почему у меня функция не импортируется.
Если нетрудно объясни, что такое позднее связывание, а то я почему то думал, что динамическая компановка это одно и тоже. Ты уж прости меня ламу, за вопросы такие.
1) Я там код подправил чуть, просто драл из своей проги и не все под твою ситуевину исправил=))
2)Почему не экспортируется?Смотри на:
Use the extern modifier to indicate that the actual storage and initial value of a variable, or body of a function, is defined in a separate source code module. Functions declared with extern are visible throughout all source files in a program, unless you redefine the function as static.
The keyword extern is optional for a function prototype.
Use extern "c" to prevent function names from being mangled in C++ programs.
3)Позднее/раннее связывание насколько я помню вообще из области OLE/COM. Иногда кстати применяется для следующей ситуации
class A
{
int a;
virtual void inca();
};
A::inca()
{
a++;
}
class B:public A
{
int a;
void inca();
};
B::inca()
{
a = a + 2;
}
class C:public A
{
int a;
void inca();
};
C::inca()
{
a = a*a;
}
а потом уже в проге
MyFunc(A *myclass)
{
int j;
myclass->inca();
j = myclass->a;
}
А вот вызываться она может:
1)
C *cl;
MyFunc((A*)cl);
2)
B *bl;
MyFunc((A*)cl);
То есть в первом случае реально будет вызвана
C::inca()
а во втором
B::inca()
Хотя вызывали мы
A::inca()
2)Почему не экспортируется?Смотри на:
Use the extern modifier to indicate that the actual storage and initial value of a variable, or body of a function, is defined in a separate source code module. Functions declared with extern are visible throughout all source files in a program, unless you redefine the function as static.
The keyword extern is optional for a function prototype.
Use extern "c" to prevent function names from being mangled in C++ programs.
Как я понял, здесь у тебя указывается на отсутстсвие выражения extern "c" как причину того, что функция не экспортируется?
Это противоречит тому что ты же и процитировал:
The keyword extern is optional for a function prototype.
Функции прекрасно экспортируются и без extern "c".
Позднее связывание, насколько я помню книжки :-), произошло не от OLE/COM, поскольку появилось гораздо раньше, а так это именно оно - какому обьекту принадлежит функция высясняется только на этапе исполнения, а не на этапе компилляции.
[QUOTE]Originally posted by moonmike
2)Почему не экспортируется?Смотри на:
Use the extern modifier to indicate that the actual storage and initial value of a variable, or body of a function, is defined in a separate source code module. Functions declared with extern are visible throughout all source files in a program, unless you redefine the function as static.
The keyword extern is optional for a function prototype.
Use extern "c" to prevent function names from being mangled in C++ programs.
Как я понял, здесь у тебя указывается на отсутстсвие выражения extern "c" как причину того, что функция не экспортируется?
Это противоречит тому что ты же и процитировал:
The keyword extern is optional for a function prototype.
Функции прекрасно экспортируются и без extern "c".
Позднее связывание, насколько я помню книжки :-), произошло не от OLE/COM, поскольку появилось гораздо раньше, а так это именно оно - какому обьекту принадлежит функция высясняется только на этапе исполнения, а не на этапе компилляции.
Я думаю что extern в данном случае указывает скорее на то что body of a function, is defined in a separate source code module.
Насчет второго я имел ввиду, что сейчас позднее связывание упоминается более всего именно при работе с OLE/COM.