Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Нюансы памяти на стыке VC++ dll и Delphi app

38K
18 апреля 2008 года
kosoglaz
1 / / 18.04.2008
Здравствуйте!
Есть приложение из dll (на Visual C++ 6.0 SP5) и exe (на Delphi 2007).
Они обмениваются данными через функции:

1. Запрос от exe к dll на получение данных
dll:
#define EXPORTCALLstd extern "C" int __declspec(dllexport) __stdcall;
EXPORTCALLstd SendData(bool bCalculate, TfuncDelphiDataReciever *func)
exe: CppFnGetData(true,@DataReciever);

2. Отправка данных из dll в exe
dll: код C++
int SendItemData(ULONG ulAddr, ULONG ulParent, char* szType, char* szName, char* szDimension, double *Values, UINT uiValuesCnt, char* ValuesStr, char* szDescription, char* szInnerName)
{
...
/*ulAddr - адрес объекта в dll.
Получается так:
внутри объекта
ulAddr = (ULONG)this;
SendItemData(ulAddr,...);
*/
(*DelphiDataReciever)(ulAddr,ulParent,szName,szType,szDimension,Values,uiValuesCnt,ValuesStr,szDescription,szInnerName);
...


}

exe: function DataReciever(ulAddr:longword; ulParent:longword; pszName:PChar; pszType:PChar; pszDimension:PChar; Values:PDouble; uiValuesCnt:word; pszValuesStr:PChar; pszDescription:PChar; pszInnerName:PChar):integer;stdcall;

3. Изменение данных в dll. Вызывает exe
exe: CppFnSetItemData: function(ulDataAddr:Cardinal; pszType:PChar; Values:PDouble; uiValuesCnt:longword; pszValuesStr:PChar):integer; stdcall;
dll: код C++
EXPORTCALLstd ChangeItemData(ULONG uiDataAddr, char* szType, double* Values, UINT uiValuesCnt, char* szValuesStr)
{
...
ivObject* obj = (ivObject*)uiDataAddr;
...
if(strcmp(szType,cc_ItemType_Real) == 0)
{
*((ivReal*)obj) = Values[0];
}
...

}

Данные из dll в exe передаются отлично, многократно, точно и без запинок.
Но!
Если поменять данные, т.е. вызвать из exe ф-ию dll-ки ChangeItemData, то:
E1) объект по адресу находится именно тот. Проверял много раз на дебагере, все адреса, все значения полей объекта, всё верно.
E2) значение ivReal::value (ivReal & operator = ( double val ) { value = val ; return *this; }; сам value в protected зоне) меняется, с того какое действительно есть, на какое указано

E3) Суть проблемы.
После изменения данных при повторной отсылке из dll в exe (см п. 1, 2) в dll коде появляются откровенные глюки.
Например прикод C++

void ivReal::SaveStructureData(ULONG ulParent)
{
#ifdef _DLL32
//try
//{
CString name = "";

if (!IsHide())
{
ULONG ulAddr = (ULONG)this;
//ULONG ulAddr = (ULONG)(&value);
tmpReal *tmp = GetTmpReal();
ASSERT( tmp != NULL ) ;

//ПАДАЕТ ТУТ
CString Dimension;
if( tmp->dim )
tmp->dim->GetNameElem(Dimension, eRus);

CString ValueStr;


при вызове GetNameElemкод C++

void Dimension::GetNameElem( CString &nm , eLang el )
{
POSITION ps = dimS.FindIndex( indElem ) ;
if( ps )
dimS.GetAt( ps )->GetName( nm , el ) ;

}

падение происходит внутри CObList::FindIndex, родной MFC-ой функции. (CTypedPtrList< CObList , ElemDimension *> dimS);
"Access violation at address 756C6156. Read of address 756C6156".
Причём не на первом считываемом элементе типа ivReal, а на 30ом.

Помогите, пожалуйста, найти, где тут собака порылась!
И что тут сделать-то?!!
(CTypedPtrList с указателями на объекты вместо прямого обращения к объектам по указателям уже использовал. Результат тот же)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог