Форум программистов CODEBY.NET Хостинг в Беларуси — Active Technologies

Разработка бизнес сайтов

Нужны клиенты? Тогда сюда быстрее...
X   Сообщение сайта
(Сообщение закроется через 2 секунды)

Здравствуйте, гость ( Вход | Регистрация )




> Нюансы памяти на стыке Vc++ Dll и Delphi App, помогите найти, где собака порылась
Kosoglaz
Вставить ник
сообщение 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
 
Новая тема 
Ответов (1 - 3)
gamecreator
Вставить ник
сообщение 18:04:2008, 17:09
Цитата Ответить 


Гуру
***

Группа: Достойный программист
Сообщений: 315
Регистрация: 3:11:2007
Пользователь №: 13 517



Репутация: - 1 +


Может екзешник вызывает функцию другим типом вызова?
Подняться вверх 
 
Сообщение #2
Yason
Вставить ник
сообщение 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
Kosoglaz
Вставить ник
сообщение 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


Быстрый ответ  Ответить  Новая тема 

> Быстрый ответ
Полужирный
Курсив
Подчеркнутый
Вставить изображение
Смайлики
Цитата
Код
 
 Отправлять уведомления об ответах на e-mail |  Включить смайлики |  Добавить подпись
   

 

RSS Текстовая версия Сейчас: 20:07:2008 - 22:25
с нами можно связаться по:
телефону: +375-(29)-632-60-67
e-mail:info@codeby.net