Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Позднее связываение с DLL

3.2K
23 апреля 2003 года
borlan
6 / / 15.04.2003
У меня есть 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.
358
23 апреля 2003 года
moonmike
423 / / 18.10.2002
Цитата:
Originally posted by borlan
У меня есть 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?

3.2K
23 апреля 2003 года
borlan
6 / / 15.04.2003
Цитата:
Originally posted by moonmike

Скорее всего надо писать вот так:
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 где реализована функция. В таблице экпорта посмотрел моя функция есть.

358
23 апреля 2003 года
moonmike
423 / / 18.10.2002
Цитата:
Originally posted by borlan


Попробовал не помогло.
В 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);
}

358
23 апреля 2003 года
moonmike
423 / / 18.10.2002
И кстати ЗЫ:
Называется это динамической компоновкой а не поздним связыванием.
3.2K
23 апреля 2003 года
borlan
6 / / 15.04.2003
Цитата:
Originally posted by moonmike
И кстати ЗЫ:
Называется это динамической компоновкой а не поздним связыванием.



Спасибо, получилось по твоему способу, хотя я и не понял почему у меня функция не импортируется.
Если нетрудно объясни, что такое позднее связывание, а то я почему то думал, что динамическая компановка это одно и тоже. Ты уж прости меня ламу, за вопросы такие.

358
23 апреля 2003 года
moonmike
423 / / 18.10.2002
Цитата:
Originally posted by borlan


Спасибо, получилось по твоему способу, хотя я и не понял почему у меня функция не импортируется.
Если нетрудно объясни, что такое позднее связывание, а то я почему то думал, что динамическая компановка это одно и тоже. Ты уж прости меня ламу, за вопросы такие.


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()

362
24 апреля 2003 года
_kolyan
339 / / 03.12.2002
[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, поскольку появилось гораздо раньше, а так это именно оно - какому обьекту принадлежит функция высясняется только на этапе исполнения, а не на этапе компилляции.
358
24 апреля 2003 года
moonmike
423 / / 18.10.2002
Цитата:
Originally posted by _kolyan
[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.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог