IMHO.WS

IMHO.WS (http://www.imho.ws/index.php)
-   Программирование (http://www.imho.ws/forumdisplay.php?f=40)
-   -   DLL написанная на С++ в Delphi (http://www.imho.ws/showthread.php?t=123792)

SeriousSEMEN 19.09.2007 17:52

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 и менее символов всё работает, а для большего колличества - НЕТ?

Если кто знает, помогите решить проблему :молись:

PSyton 20.09.2007 07:05

Скорее всего проблемы с выделением памяти.
Если мне не изменяет память, то CString имеет маленький статический буфер для коротких строк, а если строка длинее этого буфера, то используется динамическия память.
Проблема может быть (и скорее оно так и есть) в несовместимости рантаймов вызываемой функции и вызывающей.
Использование MFC классов для внешних интерфейсов не самая хорошая идея. Почему бы не использовать TCHAR* и PCHAR (delphi)?
void __stdcall EXPORT hash(TCHAR* inStr, TCHAR* outStr);
Понятно что тогда нужно самому контролировать размеры и т.п.

SeriousSEMEN 20.09.2007 10:09

PSyton
Но ведь при чтении стоки из файла всё проходит отлично.

solarian 20.09.2007 12:10

А дельфийский string разве совместим по формату в памяти с CString из MFC? В старых Delphi их без преобразования в char* никак нельзя было передать в C/C++.

PSyton 20.09.2007 13:17

Цитата:

Сообщение от SeriousSEMEN (Сообщение 1460694)
PSyton
Но ведь при чтении стоки из файла всё проходит отлично.

Я сделал логичное предположение
solarian
CString из MFC, да и вообще MFC вещь сама в себе и потому не очень дружит с внешними вещами.
А строки не совместимы на 100% в паскале String вида <размер <строки>сама строка>, а в C++ все строки это строки с завершающим нулем. И то что когда-то это работает - сущей воды везение.

В общем char*/TCHAR* решают все проблемы, потому что это нативные типы. Вы бы еще stl::string засунули в паскаль.

SeriousSEMEN 24.09.2007 16:31

PSyton
Ты оказался прав. Вот только чтобы не переделывать всю библиотеку, зделал так :biggrin:
CString __stdcall HASH(char *NAME)
{
CString PASS;
PASS=NAME;
...

sflash 02.10.2007 13:58

А можно пойти и другим путем :) В Delphi определить тип аналогичный Cstring и все пойдет :)


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

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