Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / DLL как передать строку / 25 сообщений из 33, страница 1 из 2
16.12.2003, 12:35
    #32353731
new one
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
Такой вопрос, есть DLL в ней есть функция
которая возращает String
при этом я подключаю функцию, она срабатывает, дает результат,
но после того как она отработала выбивает ошибку

Invalid pointer operation

может подскажет кто что здесь к чему, (когда работаю с int то все работает без проблем)
...
Рейтинг: 0 / 0
16.12.2003, 13:01
    #32353772
_Konst
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
совпадает ли calling convention в декларации ф-ии и при определнии указателя на нее? Стек может неправильно подчищаться, если ф-ия объявлена как __stdcall, а в объявленном вами указателе по умолчанию использовалось __cdecl
...
Рейтинг: 0 / 0
16.12.2003, 13:22
    #32353820
new one
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
дело в том, что функция в принципе работает нормально, и можно вызвать несколько подряд, только вот потом, после выполнении последней, выбрасывается ошибка...
...
Рейтинг: 0 / 0
16.12.2003, 15:54
    #32354185
_Konst
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
Под debug-ом зайдите...
...
Рейтинг: 0 / 0
16.12.2003, 21:10
    #32354561
Миг
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
Очень сильное ощущение, что функция возвращает не СString а поинтер на строку. При выгрузке длл-ки строка уничтожается, и ваш поинтер указывает в никуда...
...
Рейтинг: 0 / 0
17.12.2003, 03:53
    #32354638
StarWind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
народ.... ну когда вы отучитесь передавать строки в dll... ну нельзя это.... только PChar.... или в Си не помню как вобщем указатель на нуль терминированную строку... восмотрите описание всех WinAPI и там нет обычных строк... только указатели...
...
Рейтинг: 0 / 0
17.12.2003, 11:25
    #32354940
_Konst
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
Да действительно, нельзя....

Но если очень хочется, то надо не возвращать стоку непосредственно, а присваивать нужный результат ссылке

void func(CString& str)
{
str = "data";
}
...
Рейтинг: 0 / 0
17.12.2003, 11:29
    #32354956
StarWind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
_Konst
и кто будет память чистить за этой строкой?
...
Рейтинг: 0 / 0
17.12.2003, 11:36
    #32354972
Cauchy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
Поддерживаю StarWind. Только char*.
...
Рейтинг: 0 / 0
17.12.2003, 12:57
    #32355143
_Konst
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
2 StarWind
Я передаю строку по ссылке.
Это значит, что память под нее выделена в другом модуле (EXE), а не в DLL, которой она передана. Адресное пространство DLL и EXE одно и тоже. Никаких багов возникнуть не может. Можете поэкпериментировать. Я прежде чем постить проверил, все нормально работает. Единственно, проверял для string, а не для CString, но это без разницы. Понятно, что передача по ссылке ничем не отличается от передачи указателя, которую вы пропагандируете. А уж указатель это на простой тип (char) или на составной объект (string) - никакой разницы в данном случае.
...
Рейтинг: 0 / 0
17.12.2003, 18:46
    #32355953
vdimas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
2 StarWind и иже с ним:
что за бредовые мысли - передавать только по указателю???

у нас в проекте штук 20 DLL, строки передаются и боком и раком, и std::string, и CString, и по ссылке и по значению (зачастую для возвращаемого результата) и еще char* и даже char*& и т.д.

new one,
давай саму ф-ию и строки, где она вызывается, ошибка в чем-то другом.
...
Рейтинг: 0 / 0
18.12.2003, 04:01
    #32356162
StarWind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
бредовые говоришь...
мененджеры памяти у dll и exe разные... передать строку можно
но только не стоит ее менять... возвращать строку... интересно... под нее память в dll выделена, а кто ее убьет, прости за повторение? Указатель (коим является char*) вполне можно передавать, более того в WinAPI именно так и делается и именно это и является правильным
...
Рейтинг: 0 / 0
18.12.2003, 10:28
    #32356344
vdimas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
бредовые говоришь...
мененджеры памяти у dll и exe разные... передать строку можно
но только не стоит ее менять... возвращать строку... интересно... под нее память в dll выделена, а кто ее убьет, прости за повторение?

А ты сначала в исходники загляни, потом меня спрашивай
Если строка - объект, то она "сама" разберется,
если выделена как массив char в памяти по new, то тут ты САМ должен знать, КАК ИМЕННО она была выделена, - это твое приложение, по умолчанию CRT использует Heap API и все работет без проблем. Если юзаешь свои heap-ы, то ими и оперируй, в чем проблема-то?

Указатель (коим является char*) вполне можно передавать, более того в WinAPI именно так и делается и именно это и является правильным
Ой ли? Это всего-навсего переносимый вид представления и не более того. А те API ф-ии, которые ВОЗВРАЩАЮТ строку, требуют указатель на буфер, куда строку класть... Прочти, например, текст из окна с помощью API (как минимум 2 вызова...), удобно?
...
Рейтинг: 0 / 0
18.12.2003, 12:39
    #32356544
_Konst
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
2 vdimas
Гм...
Хотелось бы посмотреть как это вы научились возвращать объекты из ф-ии.
У меня, например, не получилось. Никакие calling conversion не помогают.
Точнее возврат объекта проходит в том случае, если он не выделяет для своих данных памяти.
Такой объект можно нормально вернуть:
class COb
{
public:
COb(int i) : m_i(i){}
COb(const COb& in) { m_i = in.m_i; }
int m_i;
};

А вот такой уже нет:
class COb
{
public:
COb(int i) { m_pi = new int(i);}
COb(const COb& in) { m_pi = new int(*in.m_pi); }
~COb() { delete m_pi;}
int *m_pi;
};

Dll экспортирует ф-ию
COb func(int i)
{
return COb(i);
}

Exe падает, когда вызывается деструктор для временного возвращаемого объекта COb(i).
Мы тут провели исследование
...
Всему виной, по-видимому, разные менеджеры памяти для dll и exe. Если вызовы new и delete заменить на HeapCreate, HeapAlloc и HeapDestroy соотвественно, то все нормально прокатывает!
Только вот string и CString видимо используют стандартный менеджер памяти библиотеки RunTime, поэтому возвращать объекты этих классов в качестве значений в общем случае нельзя, если, конечно, вы не изголились и не переопределили new для своих объектов.
...
Рейтинг: 0 / 0
18.12.2003, 13:35
    #32356671
DJStealth
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
А вот так писать в DLL не пробовал?
Код: plaintext
1.
2.
extern  "C"  __declspec(dllexport) void GetAboutInfo(LPCSTR strFileVer, LPCSTR strCopy, LPCSTR strFileDescr);
extern  "C"  __declspec(dllexport) CString AfxConnectionWnd(int pFrame);
extern  "C"  __declspec(dllexport) void AfxSplashScreen(LPCSTR strFileVer, LPCSTR strCopy, LPCSTR strFileDescr);

и эти функции будут возвращать из длл то что тебе надо, зачем велосипед заново конструировать
...
Рейтинг: 0 / 0
18.12.2003, 14:13
    #32356763
DJStealth
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
Експлопер блин глючит.
Так вот указываешь в DLL свои функции, которые будут видны их EXE, а внутри них делай, что хочешь и как хочешь
...
Рейтинг: 0 / 0
18.12.2003, 21:16
    #32357355
vdimas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
2 _Konst

2 vdimas
Гм...
Хотелось бы посмотреть как это вы научились возвращать объекты из ф-ии.
У меня, например, не получилось. Никакие calling conversion не помогают.
[кусь...]
Всему виной, по-видимому, разные менеджеры памяти для dll и exe. Если вызовы new и delete заменить на HeapCreate, HeapAlloc и HeapDestroy соотвественно, то все нормально прокатывает!

Гм, Гкхм, Кхе-кхе-а-а, уффф!..
Знаешь, а exe и dll на одном и том же С++ написаны???

У меня однажды подобная проблема была, когда я в одном месте переопределил глобальный new, а в других ЗАБЫЛ!!! Если же использую или только по-умолчанию или везде свой менеджер, то ВСЕ РАБОТАЕТ!

Я бы сказал - давай исходники, поищу ВАШУ ошибку, но совершенно занят последнее время :)

Повторю, у меня в проекте тонна DLL, объекты тоже возвращаются и по значению и по-всякому, и раком и боком. И даже в конструкторах или в процессе работы создают динамические объекты, а умирают вообще где ни попадя, и даже в соседних тредах, не то что в соседних DLL или основном exe. Так что надо искать ошибку :)
...
Рейтинг: 0 / 0
18.12.2003, 21:19
    #32357361
vdimas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
стой, мысля появилась!

проверь, все ли DLL и exe скомпилены с одной и той же опцией насчет линкования MFC.

Помню, у меня как-то были проблемы, когда я использовал различные способы использования MFC в разных DLL. Т.е., если юзаешь мультипоточный MFC в виде DLL, так проверь, чтобы все модули именно так его юзали...
...
Рейтинг: 0 / 0
19.12.2003, 05:19
    #32357432
StarWind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
объект созданный одним манагером разрушается другим??? Ты хоть думай прежде чем говорить. Это возможно только при одинаковых менеджерах памяти! Если в C это так, то да, но в общем случае это не так!!!
"Это всего-навсего переносимый вид..." это куда мы собрались что переносить? Это всего лишь правилльное решение не зависящее от приложеня от того на чем оно написано и прочее!!! Если всего этого не нужно... то я пережавал и объекты безо всяких заморочек, вот только вызвать эту dll могло приложение только при определенных условиях!
...
Рейтинг: 0 / 0
19.12.2003, 18:13
    #32358585
_Konst
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
2 vdimas

Да нет, MFC тут не причем.
Но на всякий случай скажу - в опциях и того и другого проекта указано, что MFC не используется. Программа падает, когда менеджер памяти подчищает то, что было выделено. Это происходит на вызове ф-ии Rumtime _free_dbg, а точнее в _CrtIsValidHeapPointer, а еще точнее в HeapValidate.
Отсюда вывод, что по крайней мере по умолчанию в Visual C++ 6 и по крайней мере в дебагерной версии менеджеры памяти для dll и exe разные. Возможно их можно привести в соответствие.

Вызов HeapValidate выглядит так:
if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), TRUE))
return FALSE;
...
HeapValidate( _crtheap, 0, pHdr(pUserData) );// Брык...
pUserData - это указатель на то, что я удаляю по delete - вполне корректный указатель. До самого последнего момента *pUserData дает в отладчике именно то, что там должно быть.

Т.е. можно предположить, что текущий _crtheap не совпадает с тем, который использовался при выделении pUserData.

Если не лень читать привожу код 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.
57.
class COb
{
public:
	COb();
	COb(int hh);
	COb(const COb& in);
	COb& operator= (const COb& in);
	~COb();

	int *m_phh;
	HANDLE m_heap;
};

COb::COb() : m_phh( 0 )
{
	//m_heap = HeapCreate(HEAP_NO_SERIALIZE,  4 ,  8 );
	//m_phh = (int*)HeapAlloc(m_heap, HEAP_ZERO_MEMORY,  4 );
	m_phh = new int( 0 );
	*m_phh =  0 ;
}

COb::COb(int hh)
{
	//m_heap = HeapCreate(HEAP_NO_SERIALIZE,  4 ,  8 );
	//m_phh = (int*)HeapAlloc(m_heap, HEAP_ZERO_MEMORY,  4 );
	m_phh = new int( 0 );
	*m_phh = hh;
}

COb::COb(const COb& in) : m_phh( 0 )
{
	//m_heap = HeapCreate(HEAP_NO_SERIALIZE,  4 ,  8 );
	//m_phh = (int*)HeapAlloc(m_heap, HEAP_ZERO_MEMORY,  4 );
	m_phh = new int( 0 );
	*this = in;
}

COb& COb::operator= (const COb& in)
{
	*m_phh =*in.m_phh;
	return *this;
}

COb::~COb()
{
	//BOOL b = HeapDestroy(m_heap);
	delete m_phh;
}

COb __stdcall func(int i);

//В cpp
COb __stdcall func(int i)
{
	return COb(i);
}



И код Exe
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
int main(int argc, char* argv[])
{
	COb (__stdcall *pFunc)(int);
	HMODULE hInst = ::LoadLibrary( "D:\\Projects\\tstDll\\Debug\\tstDll.dll" );
	if(hInst)
	{
		(FARPROC&)pFunc = ::GetProcAddress(hInst,  "func" );
		if(pFunc)
		{
			for(int i= 0 ; i< 100 ; i++)
			{
				COb ob(pFunc(i));
				int hh =  0 ;
			}
		}
	}

	return  0 ;
}


Если раскомментировать выделение памяти по хипу, то все Ок. Иначе нет.
...
Рейтинг: 0 / 0
19.12.2003, 20:36
    #32358660
vdimas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
ok, попробую у себя...
...
Рейтинг: 0 / 0
19.12.2003, 20:53
    #32358664
vdimas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
Код: plaintext
1.
2.
3.
COb::COb(const COb& in)
{
    m_phh = new int(*in.m_phh);
}


так попробуй.
...
Рейтинг: 0 / 0
19.12.2003, 21:03
    #32358665
vdimas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
2 StarWind

объект созданный одним манагером разрушается другим??? Ты хоть думай прежде чем говорить. Это возможно только при одинаковых менеджерах памяти! Если в C это так, то да, но в общем случае это не так!!!
"Это всего-навсего переносимый вид..." это куда мы собрались что переносить? Это всего лишь правилльное решение не зависящее от приложеня от того на чем оно написано и прочее!!! Если всего этого не нужно... то я пережавал и объекты безо всяких заморочек, вот только вызвать эту dll могло приложение только при определенных условиях!

Даже не знаю, как на все это отвечать...
Может, по мылу или по аське вопросы задашь?.. а то как-то неохота тут буквари устраивать...
...
Рейтинг: 0 / 0
20.12.2003, 03:40
    #32358748
StarWind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
vdimas
тебе доказывать что-то...
я еще с контроллерами понял. Делай как хочешь, только избави бог нам (как юридичаскому лицу) связываться с твоей конторой...
...
Рейтинг: 0 / 0
20.12.2003, 07:46
    #32358757
vdimas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DLL как передать строку
2 StarWind
тебе доказывать что-то...
я еще с контроллерами понял. Делай как хочешь, только избави бог нам (как юридичаскому лицу) связываться с твоей конторой...

Странный ты, однако...
В том случае с контролеррами я тоже попросил ОБОСНОВАНИЙ, хотя бы одно... так и не услышал ничего из технической области. Если уж споришь, так спорь по-существу, приводи аргументы, а не охай.

У меня мыло и все остальное открыто как раз на тот случай, чтобы вещи азбучного характера не постить сюда... и мне вовсе не жалко (было) потратить 10 мин в аське, дабы кому-то ответить лично. Твой первый пост - полнейший бред, с т.з. С++, более того, он утверждает, что стандарты С++ отныне не работают. Я же утверждаю, что про С++ ты только в журналах читал, потому и предложил продолжить вне форума.

А насчет твоей конторы - дык вы наверняка с нами дело имеете.
Посмотри на чайники, утюги, телеки, wireless access-points, мониторы и т.д... Что, нигде Philips не видно?
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / DLL как передать строку / 25 сообщений из 33, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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