Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / DLL и класс / 19 сообщений из 19, страница 1 из 1
26.03.2007, 13:40
    #34415496
AlexeyL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
Доброго времени суток.
Господа, возникла следющая проблема
Имеется DLL, в экспортируемых функциях вызываются методы класса, объект которого объявлен в DLL.
На всякий случай код main.cpp DLL
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
#include "Framework.h"

static Framework * Shell;

extern "C"
__declspec(dllexport)
int __stdcall 	Init(char** a)
{
	return Shell->init(a);
};

extern "C"
__declspec(dllexport)
int __stdcall 	InitCallBack(CallBackFuncType aCbInit, 
			     CallBackFuncType aCbDoProcess, 
			     CallBackFuncType aCbTerm, 
			     char** a)
{ 
	return Shell->initCallBack(aCbInit, aCbDoProcess, aCbTerm, a);
};

extern "C"
__declspec(dllexport)
int	__stdcall DoProcess( char* src, char* dst, char* fileprefix, char** encode_info  ) 
{
	Shell->initialize();
	return Shell->processData(src, dst, fileprefix, encode_info);
};

extern "C"
__declspec(dllexport)
int	__stdcall	ShowConfig()
{
	return  0 ;
} 


extern "C"
__declspec(dllexport)
int	__stdcall Term(char** ErrorMsg)
{
	Shell->term();
	return  0 ;
};

extern "C" BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ulReason,
					LPVOID lpReserved)
{
	if (ulReason == DLL_PROCESS_ATTACH)
		Shell = new Framework();
	else if (ulReason == DLL_PROCESS_DETACH)
		delete Shell;
	
	return TRUE;    // ok
}


Эта библиотека вызывается в Delphi.
(Зачем encode_info передаётся как char ** не спрашивайте, ибо не знаю и изменить не могу).
При отработке функции DoProcess в encode_info помещается информация, которая используется уже в самой Delphi. Из Delphi вызывается с параметром типа var PChar.
Проблема в том, что из DoProcess ничего не выходит. Т.е. если смотреть в дебаге с заходом в DLL, то в эту переменную нужные данные ложатся, а при выходе из функции, последный переданный параметр - пустой.
Подсказали, что проблема с выделением и освобождением памяти, но что конкретно - не могу понять.
...
Рейтинг: 0 / 0
26.03.2007, 13:44
    #34415512
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
AlexeyLПодсказали, что проблема с выделением и освобождением памяти, но что конкретно - не могу понять.

Возможно входные параметры не корректные.
...
Рейтинг: 0 / 0
26.03.2007, 13:50
    #34415531
AlexeyL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
Akh AlexeyLПодсказали, что проблема с выделением и освобождением памяти, но что конкретно - не могу понять.

Возможно входные параметры не корректные.
Самое интересное - если написать маленькую программу на С++, которая вызывает те же методы, то возвращается нормально, а при вызове из Delphi - проблема.
Причём, в эту функцию ещё передаются все четыре параметра и все они используются внутри неё корректно, а вот информация наружу не передаётся.
...
Рейтинг: 0 / 0
26.03.2007, 13:56
    #34415549
Карабас Барабас
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
AlexeyLпроблема с выделением и освобождением памятиспособ передачи параметров одинаковый в проге на С++ и дельфи ?
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
26.03.2007, 14:00
    #34415571
AlexeyL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
Карабас Барабас AlexeyLпроблема с выделением и освобождением памятиспособ передачи параметров одинаковый в проге на С++ и дельфи ?
Posted via ActualForum NNTP Server 1.4

И там и там stdcall
...
Рейтинг: 0 / 0
26.03.2007, 14:01
    #34415576
maXmo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
а каким образом туда ложатся данные?
...
Рейтинг: 0 / 0
26.03.2007, 14:04
    #34415588
AlexeyL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
maXmoа каким образом туда ложатся данные?
Типа такого
Код: plaintext
1.
2.
3.
4.
char lib_info[ 512 ];

sprintf(lib_info,"Не указан файл конфигурации");
*encode_info = lib_info;
...
Рейтинг: 0 / 0
26.03.2007, 14:13
    #34415628
maXmo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
ёперный театр. Память выделяется в стеке?
...
Рейтинг: 0 / 0
26.03.2007, 14:17
    #34415649
AlexeyL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
maXmoёперный театр. Память выделяется в стеке?
Память дял кого? Для lib_info? Пробовал и в стеке, и в куче - результат одинаков.
...
Рейтинг: 0 / 0
26.03.2007, 14:18
    #34415655
maXmo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
я бы порекомендовал юзать HeapAlloc в длле и HeapFree в дельфе.
...
Рейтинг: 0 / 0
26.03.2007, 14:19
    #34415660
maXmo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
но более распространённой практикой является выделение памяти вызывающим кодом.
...
Рейтинг: 0 / 0
26.03.2007, 14:26
    #34415683
AlexeyL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
maXmoя бы порекомендовал юзать HeapAlloc в длле и HeapFree в дельфе.
Вся проблема в том, что код дельфы я менять не могу.
Предысторя всего этого была такая - было несколько DLL, которые прекрасно работали и возвращали значения наружу, но функция DoProcess у них была не в объекте, а прям в самом коде. Т.е. encode_info заполнялась непосредственно в DoProcess, никуда не передаваясь.
Мне же пришлось сделать несколько классов и один фреймворк для их оборачивания. И при передаче параметров в метод фреймворка происходит то, что происходит.
...
Рейтинг: 0 / 0
26.03.2007, 14:30
    #34415704
AlexeyL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
maXmoно более распространённой практикой является выделение памяти вызывающим кодом.

lib_info - это локальная private переменная фреймворка, в которую собирается информация и затем кладётся в encode_info.
Память под encode_info выделяется в дельфе
...
Рейтинг: 0 / 0
26.03.2007, 15:09
    #34415851
maXmo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
выделяется? Точно? Раз память выделена, то чего ты тогда фигнёй страдаешь? Пиши сразу в выделенную память:
Код: plaintext
_snprintf(*encode_info, 512 ,"Не указан файл конфигурации");
а вот этот код:
Код: plaintext
*encode_info = lib_info;
ничего никуда не кладёт, он переписывает значение указателя.

Можешь привести код дельфы, чем инициализируется encode_info перед передачей в функцию?
...
Рейтинг: 0 / 0
26.03.2007, 15:28
    #34415919
AlexeyL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
maXmoвыделяется? Точно? Раз память выделена, то чего ты тогда фигнёй страдаешь? Пиши сразу в выделенную память:
Код: plaintext
_snprintf(*encode_info, 512 ,"Не указан файл конфигурации");
а вот этот код:
Код: plaintext
*encode_info = lib_info;
ничего никуда не кладёт, он переписывает значение указателя.

Можешь привести код дельфы, чем инициализируется encode_info перед передачей в функцию?

К сожалению не имею доступа к исходникам дельфы. Тестировать приходится прям из рабочего модуля. Либо на C++ делать минитест.
Код: plaintext
1.
_snprintf(*encode_info, 512 ,"Не указан файл конфигурации")
Выдаёт Access violation как в модуле, так и в тесте.
...
Рейтинг: 0 / 0
26.03.2007, 15:44
    #34415997
AlexeyL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
Вообще любое использование значения этого указателя приводит к Access Violation.
При этом, этот указатель ненулевой и там даже лежит переданные данные.
...
Рейтинг: 0 / 0
26.03.2007, 15:59
    #34416059
AlexeyL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
Блин, пролему я понял.
При тестировании выделяется память под массив чаров, затем передаётся ссылка на этот массив. Но, т.к. массив организован на стеке, то при вызове функции ссылка указывает на указатель, которого уже нет в стеке. Таким образом получается exception.
Может подскажете, как рещить это дело?
...
Рейтинг: 0 / 0
26.03.2007, 17:31
    #34416420
maXmo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
сначала тебе нужно узнать, как работает дельфовый код с той вернутой строкой. Иначе будешь ловить косяки. Можно размещать массив в куче. В принципе *encode_info = lib_info; должен работать нормально, только будет утечка памяти.
...
Рейтинг: 0 / 0
26.03.2007, 17:49
    #34416486
AlexeyL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL и класс
maXmoсначала тебе нужно узнать, как работает дельфовый код с той вернутой строкой. Иначе будешь ловить косяки. Можно размещать массив в куче. В принципе *encode_info = lib_info; должен работать нормально, только будет утечка памяти.

Спасибо. С горем пополам проблема решилась.
Допёр я как работает всё это хозяйство. На самом деле утечка памяти имеет место, но уже со стороны Дельфы, т.к. происходит следующее
- из Дельфы приходит указатель на PChar с необходимой для конфига инфой
- далее в библиотеке создаётся новый массив, в него помещается нужная информация, и уже указатель на этот массив присваивается к encode_info и передаётся в дельфи.
- затем, после копирования выведенной информации вызывается другая функция DLL, котоая удаляет этот массив.
Т.е. переданный указатель на PChar переписывается, но старое его значение не удаляется.
Жесть, танцы с бубнами. Согласен полностью, но придётся делать так.

Всем огромное спасибо, топ можно закрывать.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / DLL и класс / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]