Помощник
Здравствуйте, гость ( Вход | Регистрация )
|
|
18:04:2008, 09:14
|
|
Новенький ![]() Группа: Программист Сообщений: 4 Регистрация: 1:02:2008 Пользователь №: 15 130 Репутация: 0
|
Здравствуйте!
Есть приложение из 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,uiValuesC nt,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 с указателями на объекты вместо прямого обращения к объектам по указателям уже использовал. Результат тот же) Сообщение отредактировал European - 18:04:2008, 09:20
Причина редактирования: Установка тегов кода
|
|
Сообщение
#1
|
|
![]() |
|
|
18:04:2008, 17:09
|
|
Гуру ![]() ![]() ![]() Группа: Достойный программист Сообщений: 315 Регистрация: 3:11:2007 Пользователь №: 13 517 Репутация: 1
|
Может екзешник вызывает функцию другим типом вызова?
|
|
Сообщение
#2
|
|
|
|
19:04:2008, 13:55
|
|
Продвинутый ![]() ![]() Группа: Программист Сообщений: 135 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
К сожалению, я не очень помню размеры разных типов в дельфи, но тут явно нестыковка:
Цитата dll: int SendItemData(ULONG ulAddr, ULONG ulParent, char* szType, char* szName, char* szDimension, double *Values, UINT uiValuesCnt, char* ValuesStr, char* szDescription, char* szInnerName); EXPORTCALLstd ChangeItemData(ULONG uiDataAddr, char* szType, double* Values, UINT uiValuesCnt, char* szValuesStr) 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; CppFnSetItemData: function(ulDataAddr:Cardinal; pszType:PChar; Values:PDouble; uiValuesCnt:longword; pszValuesStr:PChar):integer; stdcall; Upd: посмотрел размеры, ULONG ulAddr - 8 байт ulAddr:longword - 4 байта UINT uiValuesCnt - 4 байта uiValuesCnt:word - 2 байта ULONG uiDataAddr - 8 байт ulDataAddr:Cardinal - 4байта Сообщение отредактировал Yason - 19:04:2008, 14:09 |
|
Сообщение
#3
|
|
|
|
22:04:2008, 11:59
|
|
Новенький ![]() Группа: Программист Сообщений: 4 Регистрация: 1:02:2008 Пользователь №: 15 130 Репутация: 0
|
gamecreator, Yason,
спасибо за советы. Буду смотреть в этом направлении. Вызов правда везде в си: #define EXPORTCALLstd extern "C" int __declspec(dllexport) __stdcall; EXPORTCALLstd [экспортируемая функция] в дельфи: [функция (импорт или экспорт)];stdcall; |
|
Сообщение
#4
|
|
![]() |
|
Текстовая версия | Сейчас: 20:07:2008 - 22:25 |