Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: COM/DCOM/ActiveX/ATL/CORBA > Подключение Com через длл


Автор: Zigrund 26.1.2011, 11:44
Здравствуйте. Только зарегился и сразу прешёл к делу.

На работе изчаю подключение com.
Подключаю в длл. Всё замечательно работате при вызове моей тестовой простенькой исполнительной программой.
Но когда мою длл вызывает основное наше приложение, где есть всякие оле сервера, то перестают вызываться функции кома. Никаких исключентй и ошибок не вылазит.
Подобный случай был, так и не разобрались в чём дело.
Мистика какая-то.

Так подключаю.
HRESULT hr = CoCreateInstance(CLSID_GeoDataUser, NULL, CLSCTX_LOCAL_SERVER, DIID_IGeoDataUser, (void**) &m_GeoDataUser );
m_GeoDataUser - интерфейс с которым работаю.
Вообще вроде всё правильно. проверил на тысячу раз. И у меня же рабоатет.

Не может быть ли там каких-нибудь пересечений с другими com объектами и оле серверами.
Подскажите, как это вылечить?
Я уже 3 день пытаюсь, и просто не понимаю в чём проблем.

Автор: xvr 26.1.2011, 11:58
Проверяйте свой COM сервер. В первую очередь работу с параметрами - не удалили ли вы где чего лишнего. И не запутались ли где с подсчетом ссылок. Не пытались ли где работать с BSTR как с wchar_t* и наоборот. И еще много чего.
Цитата(Zigrund @  26.1.2011,  11:44 Найти цитируемый пост)
И у меня же рабоатет.
Это не показатель. Ошибки в вашем COM сервере на игрушечной тестовой программе могли и не проявиться

Давайте код, будем смотреть подробно  smile 

Автор: Zigrund 26.1.2011, 12:05
Цитата(xvr @  26.1.2011,  11:58 Найти цитируемый пост)
Давайте код, будем смотреть подробно 


Пожалуйста:

Это H
Код

struct THandleCityGuide
{
public:
        __fastcall THandleCityGuide();
        __fastcall ~THandleCityGuide();
        bool __fastcall InitDll();
        bool __fastcall LoadMap(char *PathMap,double &N, double &W, double &S, double &E, double &zoom);
        INT64 __fastcall GeneratorChisel(INT64 InChislo);
        bool __fastcall DrawCityGuide(Graphics::TBitmap *bmpCityGuide,int DeltaMapXCityGuide,int DeltaMapYCityGuide);
        bool __fastcall PointToScreen(double InLongitudeCityGuide,double InLatitudeCityGuide,double &OutXCityGuide,double &OutYCityGuide);
        bool __fastcall PointToGeo(double &OutLongitudeCityGuide,double &OutLatitudeCityGuide,double InXCityGuide,double InYCityGuide);
        double ZoomCityGuide;
        INT64 SinhroStartCityGuide;
        AnsiString NameMapCityGuide;
        int dx;
        int dy;
//private:
        AnsiString PathImage;
        IGeoDataUser *m_GeoDataUser;
        IEngine *m_CgEngine;
        IChart *m_ichart;
        ICatalog *m_icatalog;
};
#endif

Это CPP
Код

//------------------------------------------------------------------------------
__fastcall THandleCityGuide::THandleCityGuide()
{
        CoInitialize(NULL);
        m_GeoDataUser = NULL;
        m_CgEngine = NULL;
        m_ichart = NULL;
        m_icatalog = NULL;
        char F[2024];
        GetModuleFileName(HInstance,F,2023);
        PathImage.printf("%s",F);
        PathImage = ExtractFilePath(PathImage);
        PathImage += "TempImage.bmp";
}
//------------------------------------------------------------------------------
__fastcall THandleCityGuide::~THandleCityGuide()
{
    try
    {
        if(m_GeoDataUser) m_GeoDataUser->Release();
        if(m_ichart) m_ichart->Release();
        if(m_CgEngine) m_CgEngine->Release();
        if(m_icatalog)
        {
            m_icatalog->RemoveAllCharts();
            m_icatalog->Release();
                }
        CoUninitialize();
    }
    catch(...)
    {
        CoUninitialize();       
    }

}
//------------------------------------------------------------------------------
INT64 __fastcall THandleCityGuide::GeneratorChisel(INT64 InChislo)
{
        INT64 *MassParamCod;
        MassParamCod = new INT64[4];
        MassParamCod[0] = 3;
        MassParamCod[1] = 257;
        MassParamCod[2] = 3571;
        MassParamCod[3] = 3571;
        InChislo /= MassParamCod[0];
        InChislo *= MassParamCod[1];
        InChislo %= MassParamCod[2];
        InChislo ^= MassParamCod[3];
        delete[] MassParamCod;
        return InChislo;
}
//------------------------------------------------------------------------------
bool __fastcall THandleCityGuide::InitDll()
{
        try
        {
                HRESULT hr = CoCreateInstance(CLSID_GeoDataUser, NULL, CLSCTX_LOCAL_SERVER, DIID_IGeoDataUser, (void**) &m_GeoDataUser );
                if(hr == S_OK && m_GeoDataUser)
                {
                    IDispatch *i_dispatch = m_GeoDataUser->GetPlugInInterface(WideString("CityGuide"));
                    if(i_dispatch)
                    {
                        i_dispatch->QueryInterface(DIID_IEngine,(void**)&m_CgEngine);
                        i_dispatch->Release();
                    }
                    else m_CgEngine = NULL;
                    m_GeoDataUser->set_PathGif(WideString(PathImage));
                                        m_GeoDataUser->PathGif = WideString(PathImage);
                }
                else
                {
                    m_ichart = NULL;
                    m_CgEngine = NULL;
                    m_GeoDataUser = NULL;
                    m_icatalog = NULL;
                }
                return true;
        }
        catch(...)
        {
                if(m_GeoDataUser)
                {
                        m_GeoDataUser->Release();
                        m_GeoDataUser = NULL;
        }
        if(m_ichart)
        {
            m_ichart->Release();
            m_ichart = NULL;
        }
        if(m_CgEngine)
        {
            m_CgEngine->Release();
            m_CgEngine = NULL;
        }
        if(m_icatalog)
        {
            m_icatalog->Release();
            m_icatalog = NULL;
                }
                return false;
        }
}
//------------------------------------------------------------------------------
bool __fastcall THandleCityGuide::LoadMap(char *PathMap,double &N, double &W, double &S, double &E, double &zoom)
{
    AnsiString InPath;
    InPath.printf("%s",PathMap);
    bool StatuS = false;
    if(m_CgEngine)
    {
        try
        {
            IDispatch *i_dispatch = m_CgEngine->ChartsCatalog;
            if(i_dispatch)
            {
                i_dispatch->QueryInterface(DIID_ICatalog,(void**)&m_icatalog);
                i_dispatch->Release();
            }
            else
            {
                m_icatalog = NULL;
                return StatuS;
                        }
                 m_CgEngine->Init(WideString(PathMap));
            i_dispatch = m_CgEngine->Chart;
            if(i_dispatch)
            {
                i_dispatch->QueryInterface(DIID_IChart,(void**)&m_ichart);
                i_dispatch->Release();
            }
            else
            {
                m_ichart = NULL;
                return StatuS;
            }
            m_ichart->GetGeoArea(&N,&W,&S,&E);
            ZoomCityGuide = zoom = m_ichart->Scale;
            m_GeoDataUser->SetGeoParam((N + S) / 2, (W + E) / 2,zoom);
                        NameMapCityGuide = AnsiString(m_ichart->get_LocalTitle());
                        //m_GeoDataUser->SetScreenSize(500,500);
                        //m_GeoDataUser->Draw();
            StatuS = true;
        }
        catch(...)
        {
                        return StatuS;
                }
    }
    return StatuS;
}
//------------------------------------------------------------------------------
bool __fastcall THandleCityGuide::DrawCityGuide(Graphics::TBitmap *bmpCityGuide,int DeltaMapXCityGuide,int DeltaMapYCityGuide)
{
        bool StatuS = false;
        bmpCityGuide->Canvas->Lock();
        try
        {
                if(m_GeoDataUser)
                {


                        //m_GeoDataUser->SetScale(ZoomCityGuide,bmpCityGuide->Width / 2,bmpCityGuide->Height / 2);
                        //m_GeoDataUser->SetScreenSize(bmpCityGuide->Width,bmpCityGuide->Height);
                        m_GeoDataUser->SetScreenSize(500,500);
                        //m_GeoDataUser->ShiftScreen(-DeltaMapXCityGuide,-DeltaMapYCityGuide);
                        m_GeoDataUser->PathGif = WideString(PathImage);
                        m_GeoDataUser->set_PathGif(WideString(PathImage));
                        //m_GeoDataUser->set_PathGif(L"C:\\Test1.bmp");
                        Application->MessageBox(AnsiString(m_GeoDataUser->PathGif).c_str(),0,0);
                        m_GeoDataUser->Draw();
                        Beep(1500,50);
                        Application->MessageBox(AnsiString(m_GeoDataUser->get_PathGif()).c_str(),0,0);
                        Application->MessageBox(PathImage.c_str(),0,0);
                        //bmpCityGuide->LoadFromFile(PathImage);
                        bmpCityGuide->Canvas->Unlock();
                        StatuS = true;
                        Beep(500,50);

                }
                return StatuS;
        }
        catch(...)
        {
                bmpCityGuide->Canvas->Unlock();
                return StatuS;
        }
}
//------------------------------------------------------------------------------
bool __fastcall THandleCityGuide::PointToScreen(double InLongitudeCityGuide,double InLatitudeCityGuide,double &OutXCityGuide,double &OutYCityGuide)
{
        bool StatuS = false;
        try
        {
                if(m_GeoDataUser)
                {
                        InLatitudeCityGuide *= PiDev180;
                        InLongitudeCityGuide *= PiDev180;
                        m_GeoDataUser->GeoToScreen(InLatitudeCityGuide,InLongitudeCityGuide,&OutXCityGuide,&OutYCityGuide);
                        StatuS = true;
                }
                return StatuS;
        }
        catch(...)
        {
                return StatuS;
        }
}
//------------------------------------------------------------------------------
bool __fastcall THandleCityGuide::PointToGeo(double &OutLongitudeCityGuide,double &OutLatitudeCityGuide,double InXCityGuide,double InYCityGuide)
{
        bool StatuS = false;
        try
        {
                if(m_GeoDataUser)
                {
                        m_GeoDataUser->ScreenToGeo(InXCityGuide, InYCityGuide,&OutLatitudeCityGuide,&OutLongitudeCityGuide);
                        OutLatitudeCityGuide *= GradDevPi;
                        OutLongitudeCityGuide *= GradDevPi;
                        StatuS = true;
                }
                return StatuS;
        }
        catch(...)
        {
                return StatuS;
        }
}
//------------------------------------------------------------------------------


Добавлено @ 12:05
Вроде всё просто.
Я конечно начинающий программист. 

Автор: Zigrund 26.1.2011, 15:11
В программе, в которой не работает касяк возникат тут: bool __fastcall THandleCityGuide::DrawCityGuide(Graphics::TBitmap *bmpCityGuide,int DeltaMapXCityGuide,int DeltaMapYCityGuide)

                        //m_GeoDataUser->SetScale(ZoomCityGuide,bmpCityGuide->Width / 2,bmpCityGuide->Height / 2);
                        //m_GeoDataUser->SetScreenSize(bmpCityGuide->Width,bmpCityGuide->Height);
                        m_GeoDataUser->SetScreenSize(500,500);
                        //m_GeoDataUser->ShiftScreen(-DeltaMapXCityGuide,-DeltaMapYCityGuide);
                        m_GeoDataUser->PathGif = WideString(PathImage); // путь удаляется и не усчтанавливается.
                        m_GeoDataUser->set_PathGif(WideString(PathImage)); // путь удаляется и не усчтанавливается.

                        //m_GeoDataUser->set_PathGif(L"C:\\Test1.bmp");
                        Application->MessageBox(AnsiString(m_GeoDataUser->PathGif).c_str(),0,0);
                        m_GeoDataUser->Draw(); // а здесь ниччего не рисуется.

                        Beep(1500,50);
                        Application->MessageBox(AnsiString(m_GeoDataUser->get_PathGif()).c_str(),0,0); // тут ничего не вызывается
                        Application->MessageBox(PathImage.c_str(),0,0);
                        //bmpCityGuide->LoadFromFile(PathImage);
                        bmpCityGuide->Canvas->Unlock();
                        StatuS = true;
                        Beep(500,50);
                        //Но никаких исключений нет.


Но при этов когда сначала вызывалась функция:
bool __fastcall THandleCityGuide::LoadMap(char *PathMap,double &N, double &W, double &S, double &E, double &zoom)

всё было корректное. Проверял.



Если после Draw вставить это:

LPVOID lpMsgBuf;
                        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMsgBuf,0,NULL);
                        MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );



То вернёт: "не удаётся найти указанный файл"

Автор: xvr 26.1.2011, 16:06
А что лежит в PathImage? Может этого файла действительно нет (или он лежит не там). И что возвращает set_PathGif?

Еще, как описанна проперть PathGif ? Если как BSTR то присваивать ей напрямую WideString нельзя, может сломаться (а может и нет)

И еще, GeoDataUser - ваше творение, или чье то стороннее?

PS. Вот тут -
Код

                      m_GeoDataUser->PathGif = WideString(PathImage); // путь удаляется и не усчтанавливается.
                       m_GeoDataUser->set_PathGif(WideString(PathImage)); // путь удаляется и не усчтанавливается.
 
одна из строк лишняя, т.к. они обе делают одно и тоже

Добавлено через 4 минуты и 9 секунд
Цитата(Zigrund @  26.1.2011,  15:11 Найти цитируемый пост)
Но при этов когда сначала вызывалась функция:
bool __fastcall THandleCityGuide::LoadMap
Может ее и надо было сначала позвать (или выполнить ту инициализацию, что в ней выполняется)?


Автор: Zigrund 27.1.2011, 08:49
Цитата(xvr @ 26.1.2011,  16:06)
А что лежит в PathImage? Может этого файла действительно нет (или он лежит не там). И что возвращает set_PathGif?

Еще, как описанна проперть PathGif ? Если как BSTR то присваивать ей напрямую WideString нельзя, может сломаться (а может и нет)

И еще, GeoDataUser - ваше творение, или чье то стороннее?

PS. Вот тут -
Код

                      m_GeoDataUser->PathGif = WideString(PathImage); // путь удаляется и не усчтанавливается.
                       m_GeoDataUser->set_PathGif(WideString(PathImage)); // путь удаляется и не усчтанавливается.
 
одна из строк лишняя, т.к. они обе делают одно и тоже

Добавлено @ 16:11
Цитата(Zigrund @  26.1.2011,  15:11 Найти цитируемый пост)
Но при этов когда сначала вызывалась функция:
bool __fastcall THandleCityGuide::LoadMap
Может ее и надо было сначала позвать (или выполнить ту инициализацию, что в ней выполняется)?

В PathGif хранится путь к файлу, с которым работате ком  объект.

Я сначала и вызываю мою функцию InitDll, там устанавливаю переменную, потом мою bool __fastcall THandleCityGuide::LoadMap,
ТАм эта переенная есть и доступ к ней нормальной. 
А потом по ходу выполнения исполнительной программы в которой не работает, вызывается функция рисования, и в ней йже ничего не работате. Как буд-то доступ блакируется.

Да, Вы совершенно правы, там одна лишняяя, просто я пытался всеми способами ееё установить. Но ничего не помогло. 
А при работе с моей exe и одной любой строки достатточно, а лучше там вообще не одной, потому, что я её установил до этого в InitDll. И с моим exe не теряется доступ.


У меня подобная ситуация была. 
Тоже юзал функции  CoInitialize(NULL); CoUninitialize();   
У меня всё работало. При том код был проверен, а на другом не моём exe не работало. 
Я склоняюсь, что что-то не так с исполнителной программой. Что там такое может быть.
Повторюсь, там используется  какой-то оле сервер. 
Мог там программер ошибиться, что мой софтинка не работает.
У меня -то всё предельно просто.


Ничего не обноляется, просто кто-то мне доступ закрывает. 

Автор: xvr 27.1.2011, 12:22
Цитата(Zigrund @  27.1.2011,  08:49 Найти цитируемый пост)
В PathGif хранится путь к файлу, с которым работате ком  объект.

Это понятно. Я спрашивал что именно там лежит (т.е. значение). Путь к файлу абсолютный или относительный? Если второе, то будут проблемы если кто то изменит текущую директорию в работающей программе (к примеру она меняется банальным вызовом диалога выбора имени файла)

Цитата(Zigrund @  27.1.2011,  08:49 Найти цитируемый пост)
Как буд-то доступ блакируется.
Это вряд ли. 

Цитата(Zigrund @  27.1.2011,  08:49 Найти цитируемый пост)
Повторюсь, там используется  какой-то оле сервер. 
Вряд ли он виноват (если он только не в конец кривой и косой  smile )


Автор: Zigrund 27.1.2011, 14:12
Цитата(xvr @ 27.1.2011,  12:22)
Цитата(Zigrund @  27.1.2011,  08:49 Найти цитируемый пост)
В PathGif хранится путь к файлу, с которым работате ком  объект.

Это понятно. Я спрашивал что именно там лежит (т.е. значение). Путь к файлу абсолютный или относительный? Если второе, то будут проблемы если кто то изменит текущую директорию в работающей программе (к примеру она меняется банальным вызовом диалога выбора имени файла)

Цитата(Zigrund @  27.1.2011,  08:49 Найти цитируемый пост)
Как буд-то доступ блакируется.
Это вряд ли. 

Цитата(Zigrund @  27.1.2011,  08:49 Найти цитируемый пост)
Повторюсь, там используется  какой-то оле сервер. 
Вряд ли он виноват (если он только не в конец кривой и косой  smile )

Абсолютный конечно. Нет, там всё железно. 

Почему спросил про блокируется, потому, что функции com вызываться перстают. Точно знаю. 

Писал оле сервак опытный программер конечно. но он его писал быстро, так как надо было срочно, и пару мест методом тыка мог сделать. как мне сказали.
У меня код проще некуда. Всего пара строк. Сами видете. Я его Вам весь целеком скинул.
Может подскажете какие-нибудь стандартные места, чтобы я попросил посмотреть, где обычно бывают ошибки:

 smile 
 
На С# вроде всё нормально работате в студии.
А на Buildere C++, вот такой вот канфуз непонятный. А надо на нём впервую очередь.

Автор: xvr 27.1.2011, 20:38
Увы, в коде вроде никакого криминала в глаза не бросается.  smile 

Автор: Zigrund 28.1.2011, 09:08
Цитата(xvr @ 27.1.2011,  20:38)
Увы, в коде вроде никакого криминала в глаза не бросается.  smile

Да, код совсем не сложный.

Тогда, может из Вашего опыта подскажите, какие бывают типовые ошибки при использовании оле сервера, и мы их поищем в exe приложении в котором не работает. 
Спасибо за оказанную Вами помощь. 

Автор: xvr 28.1.2011, 10:27
Цитата(Zigrund @  28.1.2011,  09:08 Найти цитируемый пост)
какие бывают типовые ошибки при использовании оле сервера

Самые частые это неправильное освобождение ресурсов (параметры освобождаются не там или не тогда, когда надо), и ошибки в подсчете ссылок (приводит к зависшим объектам или преждевременно удаленным объектам)
Еще бывают всякие баги с multithread'ом (в основном это обычные баги, но есть и некоторые специфичные для COM)


Автор: Zigrund 28.1.2011, 10:30
Цитата(xvr @ 28.1.2011,  10:27)
Цитата(Zigrund @  28.1.2011,  09:08 Найти цитируемый пост)
какие бывают типовые ошибки при использовании оле сервера

Самые частые это неправильное освобождение ресурсов (параметры освобождаются не там или не тогда, когда надо), и ошибки в подсчете ссылок (приводит к зависшим объектам или преждевременно удаленным объектам)
Еще бывают всякие баги с multithread'ом (в основном это обычные баги, но есть и некоторые специфичные для COM)

Спасибо за совет.
А посоветуйте, что-нибудь почитать, из серии "com для чайников".

Автор: jonie 29.1.2011, 12:36
Дейл Роджерсон - Inside Com. http://forum.vingrad.ru/forum/topic-63870.html

Автор: Zigrund 31.1.2011, 12:41
Цитата(jonie @ 29.1.2011,  12:36)
Дейл Роджерсон - Inside Com. http://forum.vingrad.ru/forum/topic-63870.html

Спасибо.

Автор: Zigrund 2.2.2011, 13:42
Здравствуйте.
Вообще если подключать мои функции через синхронайз, то вроде работает всё.
Но при этом появляются тормоза. 
Может есть ещё какой-нибудь пдобный способ, но пошустрее???
Подскажите пожалуйста) 

Автор: xvr 2.2.2011, 22:30
Цитата(Zigrund @  2.2.2011,  13:42 Найти цитируемый пост)
Вообще если подключать мои функции через синхронайз, то вроде работает всё.

Ага. Проблемы с апартаментами COM  smile . При синхронайэ они вызываются в основной нити приложения, а без - в той нити, где стоял вызов синхронайз. По идее прямые вызовы (без синхронайз) должны были завершаться с ошибками (т.е. не работать).
Цитата(Zigrund @  2.2.2011,  13:42 Найти цитируемый пост)
Может есть ещё какой-нибудь пдобный способ, но пошустрее???

Вам нужно отмаршалить интерфейс в тот поток, где вы его собираетесь вызывать (http://msdn.microsoft.com/en-us/library/ms693316%28v=VS.85%29.aspx и http://msdn.microsoft.com/en-us/library/ms691421%28v=VS.85%29.aspx) и потом можно вызывать. Но учтите, вызовы COM объекта пойдут из разных потоков в параллель, он может быть к этому не готов  smile 


Автор: Zigrund 3.2.2011, 11:53
Цитата(xvr @ 2.2.2011,  22:30)
Цитата(Zigrund @  2.2.2011,  13:42 Найти цитируемый пост)
Вообще если подключать мои функции через синхронайз, то вроде работает всё.

Ага. Проблемы с апартаментами COM  smile . При синхронайэ они вызываются в основной нити приложения, а без - в той нити, где стоял вызов синхронайз. По идее прямые вызовы (без синхронайз) должны были завершаться с ошибками (т.е. не работать).
Цитата(Zigrund @  2.2.2011,  13:42 Найти цитируемый пост)
Может есть ещё какой-нибудь пдобный способ, но пошустрее???

Вам нужно отмаршалить интерфейс в тот поток, где вы его собираетесь вызывать (http://msdn.microsoft.com/en-us/library/ms693316%28v=VS.85%29.aspx и http://msdn.microsoft.com/en-us/library/ms691421%28v=VS.85%29.aspx) и потом можно вызывать. Но учтите, вызовы COM объекта пойдут из разных потоков в параллель, он может быть к этому не готов  smile

Спасибо. 
Буду пытаться разобраться.
А вот ещё немного не потеме.
Функция интерфейса принимает и возвращает VARIANT.
Как в него и из него сделать double[][] (двумерный массив даблов). 

Автор: xvr 3.2.2011, 15:16
Цитата(Zigrund @  3.2.2011,  11:53 Найти цитируемый пост)
Функция интерфейса принимает и возвращает VARIANT.
Как в него и из него сделать double[][] (двумерный массив даблов).  

Сначала проверить, что в VARIANT лежит SafeArray (это массивы в понимании AX). Потом проверить, что он 2х мерный. Потом сделать требуемый 2х мерный массив double'ов и поэлементно скопировать из SafeArray'я в массив.
Если размеры массива известны заранее (и константны), то можно напрямую извлечь из SafeArray'я указатель на данные.

Автор: Zigrund 4.2.2011, 08:58
Цитата(xvr @ 3.2.2011,  15:16)
Цитата(Zigrund @  3.2.2011,  11:53 Найти цитируемый пост)
Функция интерфейса принимает и возвращает VARIANT.
Как в него и из него сделать double[][] (двумерный массив даблов).  

Сначала проверить, что в VARIANT лежит SafeArray (это массивы в понимании AX). Потом проверить, что он 2х мерный. Потом сделать требуемый 2х мерный массив double'ов и поэлементно скопировать из SafeArray'я в массив.
Если размеры массива известны заранее (и константны), то можно напрямую извлечь из SafeArray'я указатель на данные.

Вообщем там одномерный массив. 
В exe проекте всё работает а в длл опять как-то касяк. Ничего не возвращается. Передаётся вроде нормально. 

Автор: Zigrund 16.2.2011, 15:15
Всёмучаю свой ком объект.
проблема с высвыбождением памяти:

Код

if(m_GeoDataUser)
        {
            IDispatch *i_dispatch = m_GeoDataUser->GetCoordinateConverter();
            if(i_dispatch)
            {
                i_dispatch->QueryInterface(DIID_ICoordinateConverter,(void**)&icc);
                i_dispatch->Release();
            }
            if(icc)
            {
                int NewNumberElements =  2 * NumberElements - 1;
                Variant GeoArrayOut;
                Variant GeoArrayIn(OPENARRAY(int, (0, NewNumberElements)), varDouble);
                TempOdnomerMass = (double*) GeoArrayIn.ArrayLock();
                for(int i = 0; i < NumberElements ; i++)
                {
                    TempOdnomerMass[2 * i] =  Track[i][1] * PiDel180;
                    TempOdnomerMass[2 * i + 1] =  Track[i][0] * PiDel180;
                }
                GeoArrayIn.ArrayUnlock();
                GeoArrayOut = icc->GeoToScreenArray(GeoArrayIn);
                OutXY = (double*) GeoArrayOut.ArrayLock();
                for(int i = 0; i < NumberElements; i ++)
                {
                    Track[i][0] = OutXY[2 * i];
                    Track[i][1] = OutXY[2 * i + 1];
                }
                GeoArrayOut.ArrayUnlock();
                                                        VariantClear(GeoArrayOut);
                VariantClear(GeoArrayIn);
                icc->Release();
                StatuS = true;
            }
        }




Всё нормально работает, кроме этого кусочка (как раз, где обращени к ком объекту идёт):

Код

                                                        GeoArrayOut = icc->GeoToScreenArray(GeoArrayIn);
                OutXY = (double*) GeoArrayOut.ArrayLock();
                for(int i = 0; i < NumberElements; i ++)
                {
                    Track[i][0] = OutXY[2 * i];
                    Track[i][1] = OutXY[2 * i + 1];
                }
                GeoArrayOut.ArrayUnlock();
                                                        VariantClear(GeoArrayOut);


При каждои запуске где-то 1MB памяти куда-то неизвестно уходит. В чём может быть проблема?

Автор: xvr 16.2.2011, 19:13
Криминала не видно. Видимо проблема где то в другом месте

Автор: Zigrund 17.2.2011, 11:14
Цитата(xvr @ 16.2.2011,  19:13)
Криминала не видно. Видимо проблема где то в другом месте

А у меня это единственное место, где я вариант использую.
Может его как-то надо удалять особенным образом?

Автор: xvr 17.2.2011, 15:57
Цитата(Zigrund @  17.2.2011,  11:14 Найти цитируемый пост)
Может его как-то надо удалять особенным образом? 

Нет. Variant должен удаляться сам (это VCL врапер над VARIANT'ом)


Автор: Zigrund 1.3.2011, 14:20
Цитата(xvr @ 17.2.2011,  15:57)
Цитата(Zigrund @  17.2.2011,  11:14 Найти цитируемый пост)
Может его как-то надо удалять особенным образом? 

Нет. Variant должен удаляться сам (это VCL врапер над VARIANT'ом)

Я пока так и не разгодал тайну волшебного ключека. Без Variant всё нормлаьно, а с Variant память кушается.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)