imho.ws
IMHO.WS  

Вернуться   IMHO.WS > Компьютеры > Программирование
Опции темы
Старый 19.09.2007, 17:52     # 1
SeriousSEMEN
Guest
 
Сообщения: n/a

DLL написанная на С++ в Delphi

У меня появились проблемы с использованием библиотеки DLL.
Описание проблемы:
1. Есть библиотека dll в которой хеш-функция получает адрес строки, обрабатывает её и возвращает уже хеш-код. Библиотека написана на С++ с использованием MFC.
2.1. Если эту библиотеку использует программа написанная на С++, то всё проходит нормально.
2.2. Вот объявление хеш-функфии в программе
CString __stdcall EXPORT HASH(CString *NAME);
2.3. Вот код вызова хеш-функции из программы
CString StrPass;
CString StrHash;
StrHash = HASH(&StrPass);
3.1. Если же эту библиотеку использует программа написанная на Delphi, то если на обработку хеш-функцией подавать адрес строки длинной меньше 4-ёх символов, то всё проходит нормально.
3.2. Вот объявление функфии в программе
function HASH(Pass: Pointer):string;StdCall;
...
implementation
function HASH; external 'maindll.dll' name 'HASH';
3.3. Вот код вызова хеш-функции из программы
var
Str_pass: string;
Str_hash: string;
begin
...
Str_hash:=HASH(@Str_pass);
4. Если же символов в подаваемой строке будет 4 и более, то на каждый, так сказать, лишний символ выдаётся два окна ошибки (Microsoft Visual C++ Debug Library), оба со следующим текстом:
Debug Assertion Failed!
Programm: <Путь к моей программе>
File: afx.inl
Line: 177
5. Если в окнах ошибок нажать "Пропустить", то библиотека возврашает правильный результат, т.е. такой же что и в случае с программой написанной на С++.
6. Я нашел файл afx.inl и вот что нашел в строке 177 (строки указаны):
173 _AFX_INLINE TCHAR CString::operator[](int nIndex) const
174 {
175 // same as GetAt
176 ASSERT(nIndex >= 0);
177 ASSERT(nIndex < GetData()->nDataLength);
178 return m_pchData[nIndex];
179 }
7. А самое интересное, что если в хеш-функцию (переделанную немного) передавать путь к файлу где находится наша строка, то уже в библиотеке прочитав строку из файла и сделав хеш-код, всё проходит отлично, что в случае с програмой на С++, что на Delphi. Причём даже возвращая хеш-код через файл и просто возвращая.
Вопрос:
Почему для 3 и менее символов всё работает, а для большего колличества - НЕТ?

Если кто знает, помогите решить проблему
 
Старый 20.09.2007, 07:05     # 2
PSyton
Junior Member
 
Аватар для PSyton
 
Регистрация: 19.04.2002
Адрес: Дом
Пол: Male
Сообщения: 187

PSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форуме
Скорее всего проблемы с выделением памяти.
Если мне не изменяет память, то CString имеет маленький статический буфер для коротких строк, а если строка длинее этого буфера, то используется динамическия память.
Проблема может быть (и скорее оно так и есть) в несовместимости рантаймов вызываемой функции и вызывающей.
Использование MFC классов для внешних интерфейсов не самая хорошая идея. Почему бы не использовать TCHAR* и PCHAR (delphi)?
void __stdcall EXPORT hash(TCHAR* inStr, TCHAR* outStr);
Понятно что тогда нужно самому контролировать размеры и т.п.
__________________
Дураки не динозавры - они не вымрут...
PSyton вне форума  
Старый 20.09.2007, 10:09     # 3
SeriousSEMEN
Guest
 
Сообщения: n/a

PSyton
Но ведь при чтении стоки из файла всё проходит отлично.
 
Старый 20.09.2007, 12:10     # 4
solarian
Newbie
 
Регистрация: 13.09.2007
Сообщения: 12

solarian Известность не заставит себя ждать
А дельфийский string разве совместим по формату в памяти с CString из MFC? В старых Delphi их без преобразования в char* никак нельзя было передать в C/C++.
solarian вне форума  
Старый 20.09.2007, 13:17     # 5
PSyton
Junior Member
 
Аватар для PSyton
 
Регистрация: 19.04.2002
Адрес: Дом
Пол: Male
Сообщения: 187

PSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форумеPSyton Популярный человек на этом форуме
Цитата:
Сообщение от SeriousSEMEN Посмотреть сообщение
PSyton
Но ведь при чтении стоки из файла всё проходит отлично.
Я сделал логичное предположение
solarian
CString из MFC, да и вообще MFC вещь сама в себе и потому не очень дружит с внешними вещами.
А строки не совместимы на 100% в паскале String вида <размер <строки>сама строка>, а в C++ все строки это строки с завершающим нулем. И то что когда-то это работает - сущей воды везение.

В общем char*/TCHAR* решают все проблемы, потому что это нативные типы. Вы бы еще stl::string засунули в паскаль.
__________________
Дураки не динозавры - они не вымрут...
PSyton вне форума  
Старый 24.09.2007, 16:31     # 6
SeriousSEMEN
Guest
 
Сообщения: n/a

PSyton
Ты оказался прав. Вот только чтобы не переделывать всю библиотеку, зделал так
CString __stdcall HASH(char *NAME)
{
CString PASS;
PASS=NAME;
...
 
Старый 02.10.2007, 13:58     # 7
sflash
Junior Member
 
Аватар для sflash
 
Регистрация: 25.09.2003
Сообщения: 53

sflash Косячил раньше, старается исправиться
А можно пойти и другим путем В Delphi определить тип аналогичный Cstring и все пойдет
sflash вне форума  


Ваши права в разделе
Вы НЕ можете создавать новые темы
Вы не можете отвечать в темах.
Вы НЕ можете прикреплять вложения
Вы НЕ можете редактировать свои сообщения

BB код Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +4, время: 20:01.




Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.