Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с dll, нужна помощь 
:(
    Опции темы
artsb
Дата 23.5.2008, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Всем привет.
Сделал тестирующую программу. Решил некоторые функции вынести в dll. Одна из них читает файл теста в вектор. Прототип:
Код

void myOpenFile(AnsiString path, settest *settings, vector<mList>& list, bool flag)

В программе вызываю её так:
Код

#include "myList.h"
#include "settest.h"
#include <vector.h>
//...
vector<mList> list;
settest *settings;
//...
HINSTANCE dllh=NULL;
void (__stdcall *myOpenFile)(AnsiString path, settest* settings, vector<mList>& list, bool flag);
dllh=LoadLibrary((wPath+"opfi.dll").c_str());
if(dllh!=NULL)
{
        myOpenFile=(void (__stdcall *)(AnsiString, settest*, vector<mList>&, bool))GetProcAddress(dllh,"_myOpenFile");
        myOpenFile(FilePath,settings,list,false);
}
FreeLibrary(dllh);

При старте всё нормально. Работает правильно. А когда закрываю программу, выдаёт сообщение: "В программе ... была найдена ошибка. Отправть отчёт об ошибке?" (3 раза smile)
Потом решил в OnClose формы добавить строку:
Код

list.clear();

На этой строчке вылетает ошибка: External exception EEFFACE.
Если нажать ОК, а потом опять попробовать закрыть программу, выдаёт ошибку: Invalid pointer operation.

При создании dll, в комментарии было написано:
Цитата

//---------------------------------------------------------------------------
//   Important note about DLL memory management when your DLL uses the
//   static version of the RunTime Library:
//
//   If your DLL exports any functions that pass String objects (or structs/
//   classes containing nested Strings) as parameter or function results,
//   you will need to add the library MEMMGR.LIB to both the DLL project and
//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
//   if any other projects which use the DLL will be performing new or delete
//   operations on any non-TObject-derived classes which are exported from the
//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
//   the file BORLNDMM.DLL should be deployed along with your DLL.
//
//   To avoid using BORLNDMM.DLL, pass string information using "char *" or
//   ShortString parameters.
//
//   If your DLL uses the dynamic version of the RTL, you do not need to
//   explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------

Подключил библиотеку MEMMGR.LIB ко всем своим dll и exe, кинул BORLNDMM.DLL в папку с программой. Но не помогло.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
mrbrooks
Дата 23.5.2008, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



Имхо в библиотеки nвоей рекомендую избавиться от  AnsiString в пользу char *
PM MAIL   Вверх
Fazil6
Дата 23.5.2008, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 11
Всего: 60



Код

void myOpenFile(AnsiString path, settest *settings, vector<mList>& list, bool flag)

 в интерфейсе либы объекты классов. Либа и экзешник компиляются или разными компилляторами или одним, но с разными настройками. Получаешь разные CRT при создании и удалении объектов и все падает. В общем виде задача решения не имеет. Либо Один компилятор одной версии с одинаковыми настройками, либо без классов в интерфейсе
PM MAIL   Вверх
artsb
Дата 23.5.2008, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



а как быть с vector? Как передать указатель на vector в dll?

Добавлено через 1 минуту и 28 секунд
Цитата(Fazil6 @  23.5.2008,  15:53 Найти цитируемый пост)
Либо Один компилятор одной версии с одинаковыми настройками

Так и есть. Всё делаю в Builder 6.


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Fazil6
Дата 23.5.2008, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 11
Всего: 60



Цитата(artsb @  23.5.2008,  15:58 Найти цитируемый пост)
Так и есть. Всё делаю в Builder 6. 

описание твоей проблемы говорит, что так не есть. 
Настройки разные. Созданое в одном модуле не может быть коректно удалено в другом
PM MAIL   Вверх
ama_kid
Дата 23.5.2008, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 10
Всего: 95



Цитата(artsb @  23.5.2008,  15:36 Найти цитируемый пост)
Прототип:
Код
void myOpenFile(AnsiString path, settest *settings, vector<mList>& list, bool flag)
Цитата(artsb @  23.5.2008,  15:36 Найти цитируемый пост)
В программе вызываю её так:
Код
void (__stdcall *myOpenFile)(AnsiString path, settest* settings, vector<mList>& list, bool flag);
Может, конечно, и не в этом дело, но почему-то в прототипе я не увидел __stdcall...



--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
Vyacheslav
Дата 23.5.2008, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 47
Всего: 59



В этом.


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
artsb
Дата 23.5.2008, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(Fazil6 @  23.5.2008,  16:10 Найти цитируемый пост)
описание твоей проблемы говорит, что так не есть. Настройки разные. Созданое в одном модуле не может быть коректно удалено в другом

Ну я никаких настроек не менял. Может они сами...
Цитата(ama_kid @  23.5.2008,  16:40 Найти цитируемый пост)
Может, конечно, и не в этом дело, но почему-то в прототипе я не увидел __stdcall...

Цитата(Vyacheslav @  23.5.2008,  18:13 Найти цитируемый пост)
В этом.

Это я привёл прототип функции из dll без тела. А вся dll выглядит так:
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include <vector.h>
#include "myList.h"
#include "settest.h"
extern "C" __declspec(dllexport) void myOpenFile(AnsiString path, settest *settings, vector<mList>& list, bool flag);
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
        return 1;
}
//---------------------------------------------------------------------------
void myOpenFile(AnsiString path, settest *settings, vector<mList>& list, bool flag)
{
//    тело
}

Вызываю её так, как писал ранее.
Сейчас поработал с проектом, теперь при закрытии программы выдаёт такую ошибку: Abnormal program termination.


Это сообщение отредактировал(а) artsb - 23.5.2008, 22:22


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
586
Дата 23.5.2008, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 57
Всего: 146



Цитата(artsb @  23.5.2008,  23:22 Найти цитируемый пост)
А вся dll выглядит так:

Неправильно. Напиши __stdcall.

Попробуй в dll закоментировать изменения вектора. Будет появляться ошибка?
PM   Вверх
ama_kid
Дата 23.5.2008, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 10
Всего: 95



Цитата(artsb @  23.5.2008,  22:22 Найти цитируемый пост)
А вся dll выглядит так:
Код
extern "C" __declspec(dllexport) void myOpenFile(AnsiString path, settest *settings, vector<mList>& list, bool flag);
Продолжаю не видеть __stdcall при экспорте:
Код
extern "C" __declspec(dllexport) void __stdcall myOpenFile(AnsiString path, settest *settings, vector<mList>& list, bool flag);




--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
vikaz
Дата 24.5.2008, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: 10
Всего: 12



Всем добрый!
Надеюсь artsb не обитеся, что я пишу в его топике, просто новый создавать не хотелось, чтобы не продить темы по DLL.

У меня несколько вопросов:
1. Все Вы знаете icq менеджер miranda. программа написана так, что весь ее функционал хранится в библионтеках dll. Кто знает, каким образом осуществляется постоение окна настроек библиотеки? Просто у меня есть несколько соображений по этому поводу, но очень сомневаюсь в них.

2. Так же всем известно, что есть библионтеки которые отвечают за работу самой программы и являются критичными (проверка защиты программы), другие модули не являются важными (всплывающее окно). Каким образом можно осуществить такое разделение модулей?

Заранее спасибо.
 


--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
ama_kid
Дата 24.5.2008, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 10
Всего: 95



vikaz, создай свой топик smile 


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
artsb
Дата 24.5.2008, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(vikaz @  24.5.2008,  10:46 Найти цитируемый пост)
Надеюсь artsb не обитеся

Нет. smile 

ama_kid, сделал как вы советовали: добавил везде __stdcall. Теперь при закрытии программы выскакивает ошибка: Abnormal program termination. После чего программа закрывается.
Так как правильно передать указатель на вектор в dll?


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
ama_kid
Дата 24.5.2008, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 10
Всего: 95



Цитата(artsb @  24.5.2008,  15:01 Найти цитируемый пост)
Теперь при закрытии программы выскакивает ошибка: Abnormal program termination.
у меня такое возникало при работе с несколькими потоками, когда я производил некорректное завершение приложения без освобождения ресурсов потоков. 
Далее, надо бы проверить один момент - при декларировании функции через __declspec(dllexport) возможно надо при импорте объявлять указатель через __declspec(dllimport), по крайней мере MSDN это рекомендует.
Цитата(artsb @  24.5.2008,  15:01 Найти цитируемый пост)
Так как правильно передать указатель на вектор в dll?
Если честно, я никогда в DLL не передавал объекты, поэтому тут могу только посоветовать сделать немного по-другому: передать в DLL указатель на функцию из вызывающей программы, которая и будет вызываться в DLL и заполнять вектор...



--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
artsb
Дата 24.5.2008, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2280
Регистрация: 17.7.2007
Где: центр Вселенной

Репутация: 39
Всего: 64



Цитата(ama_kid @  24.5.2008,  15:37 Найти цитируемый пост)
передать в DLL указатель на функцию из вызывающей программы, которая и будет вызываться в DLL и заполнять вектор...

В этом случае нет толку от dll. :(

Сделал так:
Убрал из программы всё что связано с dll и просто скопировал функции из dll в *.cpp. Теперь ошибка "Abnormal program termination" возникает на строке delete ls;. Вот кусок кода:
Код

TStringList* ls=new TStringList();
ls->LoadFromFile(FilePath);
// в ls хранятся строки, которые я "разбираю" и "засовываю" в вектор.
delete ls; // <---- здесь ошибка

Причём если поставить перед "delete ls" строку "ls->Clear();", ошибка возникает на ней. Если же убрать эти строки - всё работает нормально. Странно, почему она не хочет удалять ls?

Это сообщение отредактировал(а) artsb - 24.5.2008, 19:58


--------------------
Чем отличается умный человек от мудрого?
Умный - выпутается из любой ситуации.
Мудрый - просто в неё не попадёт.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0879 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.