Падения программы при закрытии
От: LEugene  
Дата: 11.04.03 09:00
Оценка:
Есть СОМ-объект из которого вызывается другой СОМ-объект. Делается это примерно вот так:
IXXPtr* pPtr;
try
{
    pPtr = new IXXPtr(__uuidof(XX));
}
catch(_com_error& e)
{
    AfxMessageBox(*e.ErrorMessage());
    return;
}
BSTR bstrX1[100], bstrX2[100];
(*pPtr)->XXMethod(bstrX1, bstrX2);
delete pPtr;

Так вот, если этот кусок выполняется, то при завершении программы неск. раз выскакивает "Программа выполнила недопустимую операцию...". Не подскажете-ли, где тут собака порылась?
PS: Использую MSVC6 SP5
Re: Падения программы при закрытии
От: Ivan Россия www.rsdn.ru
Дата: 11.04.03 09:29
Оценка:
Здравствуйте, LEugene, Вы писали:

pPtr = new IXXPtr(__uuidof(XX));
delete pPtr;


Этот код неправильный, COM объекты создаются по другому, а смарт-пойнтеры, как правило создаются на стеке, а не в динамической памяти

IXXPtr pPtr(__uuidof(XX));
// а деструктор для стекового объекта вызовется автоматически
Re[2]: Падения программы при закрытии
От: LEugene  
Дата: 11.04.03 10:14
Оценка:
Здравствуйте, Ivan, Вы писали:

I>Этот код неправильный, COM объекты создаются по другому, а смарт-пойнтеры, как правило создаются на стеке, а не в динамической памяти


Что именно в этом коде неправильного? Смарт-поинтеры нельзя создавать динамически?
PS: В любом случае, создание объекта в стеке не помогло...
Re[3]: Падения программы при закрытии
От: Ivan Россия www.rsdn.ru
Дата: 11.04.03 10:24
Оценка:
Здравствуйте, LEugene, Вы писали:

LE>Что именно в этом коде неправильного? Смарт-поинтеры нельзя создавать динамически?

сорри, погорячился, так создавать можно, просто редко встретишь код, в котором смарт-пойнтер в динамической памяти создается

LE>PS: В любом случае, создание объекта в стеке не помогло...

А на чем AV ?
Re[3]: Падения программы при закрытии
От: SergH Россия  
Дата: 11.04.03 10:29
Оценка:
Здравствуйте, LEugene, Вы писали:

LE>Что именно в этом коде неправильного?


Это зависит от того, что ты хотел достьчь. Если ты хотел создать COM-объект, то этот код неправильный. Если ты хотел создать смарт-поинтер в динамисеской памяти, то правильный.

LE>Смарт-поинтеры нельзя создавать динамически?


можно. Но обычно это не нужно.

LE>PS: В любом случае, создание объекта в стеке не помогло...


Для создания COM-объекта используй метод CreateInstance смарт-поинтера.
Делай что должно, и будь что будет
Re[4]: Падения программы при закрытии
От: LEugene  
Дата: 11.04.03 10:31
Оценка:
I>А на чем AV ?
mfc42.dll
Re[4]: Падения программы при закрытии
От: SergH Россия  
Дата: 11.04.03 10:32
Оценка:
Здравствуйте, SergH, Вы писали:

SH>Здравствуйте, LEugene, Вы писали:


LE>Что именно в этом коде неправильного?

SH>Это зависит от того, что ты хотел достьчь. Если ты хотел создать COM-объект, то этот код неправильный.

Сорри, я забыл что такие смарт-поинтеры отличаются от CComPtr..
Делай что должно, и будь что будет
Re: Падения программы при закрытии
От: Tom Россия http://www.RSDN.ru
Дата: 11.04.03 10:34
Оценка:
Здравствуйте, LEugene, Вы писали:

LE>Есть СОМ-объект из которого вызывается другой СОМ-объект. Делается это примерно вот так:

LE>
LE>IXXPtr* pPtr;
LE>try
LE>{
LE>    pPtr = new IXXPtr(__uuidof(XX));
LE>}
LE>catch(_com_error& e)
LE>{
LE>    AfxMessageBox(*e.ErrorMessage());
LE>    return;
LE>}
LE>BSTR bstrX1[100], bstrX2[100];
(*pPtr)->>XXMethod(bstrX1, bstrX2);
LE>delete pPtr;
LE>

LE>Так вот, если этот кусок выполняется, то при завершении программы неск. раз выскакивает "Программа выполнила недопустимую операцию...". Не подскажете-ли, где тут собака порылась?
LE>PS: Использую MSVC6 SP5

С BSTR-ами так не работаю. Попроюуй что ниюудь типа
(*pPtr)->>XXMethod(CComBSTR("Hello"), CComBSTR("World"));
... << RSDN@Home 1.0 beta 6a >>
Народная мудрось
всем все никому ничего(с).
Re: Падения программы при закрытии
От: Артур Россия  
Дата: 11.04.03 10:44
Оценка:
Здравствуйте, LEugene, Вы писали:

мнда...

try
{
    IXXPtr pPtr(__uuidof(XX))
    _bstr_t bstrX1(::SysAllocStringLen(0,100),false);
    _bstr_t bstrX1(::SysAllocStringLen(0,200),false);
    pPtr->XXMethod(bstrX1, bstrX2);
}
catch(_com_error& e)
{
    AfxMessageBox(*e.ErrorMessage());
    return;
}

найди 10 отличий
найди 10 отличий
... << RSDN@Home 1.0 beta 6a >>
Re[2]: Падения программы при закрытии
От: LEugene  
Дата: 11.04.03 10:45
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>С BSTR-ами так не работаю. Попроюуй что ниюудь типа

Tom>
Tom>(*pPtr)->>XXMethod(CComBSTR("Hello"), CComBSTR("World"));
Tom>


Сорри, не уточнил — оба BSTR'а являются возвращаемыми параметрами и они вполне нормально возвращаются.
Re[2]: Падения программы при закрытии
От: LEugene  
Дата: 11.04.03 11:28
Оценка:
Здравствуйте, Артур, Вы писали:

А>
А>try
А>{
А>    IXXPtr pPtr(__uuidof(XX))
А>    _bstr_t bstrX1(::SysAllocStringLen(0,100),false);
А>    _bstr_t bstrX1(::SysAllocStringLen(0,200),false);
    pPtr->XXMethod(bstrX1, bstrX2);
А>}
А>catch(_com_error& e)
А>{
А>    AfxMessageBox(*e.ErrorMessage());
А>    return;
А>}
А>

А>найди 10 отличий
А>найди 10 отличий

BSTR'ы тут непричем и занесение вызова метода под try тоже. Параметры у меня возвращаемые и значения им присваиваются внутри XXMethod. Сам метод работает правильно, исключений нигде не выбрасывается.
Я подозреваю, что все дело в том, что создание объекта XX и вызов одной из его функций оставляют после себя что-то, что и является причиной ошибки. Весь вопрос в том, что-именно?
Re: Падения программы при закрытии
От: Vi2 Удмуртия http://www.adem.ru
Дата: 11.04.03 12:11
Оценка:
Здравствуйте, LEugene, Вы писали:

LE>... при завершении программы неск. раз выскакивает "Программа выполнила недопустимую операцию...".

Что, действительно, несколько раз?! У меня обычно один раз и угу, сушите весла.
LE>BSTR bstrX1[100], bstrX2[100];
LE>(*pPtr)->XXMethod(bstrX1, bstrX2);

И что действительно 100 BSTR возвращаешь?

Покажи-ка IDL определение этого метода для начала разговора.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[3]: Падения программы при закрытии
От: Артур Россия  
Дата: 11.04.03 12:39
Оценка:
Здравствуйте, LEugene, Вы писали:


LE>BSTR'ы тут непричем и занесение вызова метода под try тоже. Параметры у меня возвращаемые и значения им присваиваются внутри XXMethod. Сам метод работает правильно, исключений нигде не выбрасывается.


показывай idl!
... << RSDN@Home 1.0 beta 6a >>
Re[2]: Падения программы при закрытии
От: LEugene  
Дата: 11.04.03 13:13
Оценка:
Vi2>Покажи-ка IDL определение этого метода для начала разговора.

[id(1), helpstring("method XXMethod")] HRESULT XXMethod([out] BSTR* p_bstrX1, [out] BSTR* p_bstrX2, [out, retval] long* pVal);


Да, я тут подправил, с учетом поступивших замечаний свой код, теперь он выглядит так:
IXXPtr pPtr(__uuidof(XX));
BSTR bstrX1, bstrX2;
pPtr->XXMethod(&bstrX1, &bstrX2);

Только проблему это не решило...
Re[3]: Падения программы при закрытии
От: Артур Россия  
Дата: 11.04.03 13:37
Оценка:
Здравствуйте, LEugene, Вы писали:

А освобождать BSTR кто будет?
IXXPtr pPtr(__uuidof(XX));
CComBSTR bstrX1, bstrX2;
pPtr->XXMethod(&bstrX1, &bstrX2);


а дальше — надо смотреть реализацию XXMethod
... << RSDN@Home 1.0 beta 6a >>
Re[3]: Падения программы при закрытии
От: George Seryakov Россия  
Дата: 11.04.03 14:59
Оценка:
Здравствуйте, LEugene, Вы писали:

LE>Да, я тут подправил, с учетом поступивших замечаний свой код, теперь он выглядит так:


А зря, прикольно выглядело. Многие купились.

LE>
LE>IXXPtr pPtr(__uuidof(XX));
LE>BSTR bstrX1, bstrX2;
pPtr->XXMethod(&bstrX1, &bstrX2);
LE>

LE>Только проблему это не решило...

Показывай конструктор (включая FinslConstruct) IXX и код метода XXMethod.
GS
Re: Падения программы при закрытии
От: Gleb Zemskov  
Дата: 13.04.03 04:29
Оценка: -1
Здравствуйте, LEugene, Вы писали:

LE>Есть СОМ-объект из которого вызывается другой СОМ-объект. Делается это примерно вот так:

LE>
LE>IXXPtr* pPtr;
LE>try
LE>{
LE>    pPtr = new IXXPtr(__uuidof(XX));
LE>}
// зачем все это создавать динамически?
LE>catch(_com_error& e)
LE>{
LE>    AfxMessageBox(*e.ErrorMessage());
//это у тебя скомпилировалось? Наверное у тебя все-таки AfxMessageBox(e.ErrorMessage());
LE>    return;
LE>}
LE>BSTR bstrX1[100], bstrX2[100];
//здесь у тебя абсолютно неправильная конструкция, которая действительно может давать ошибки 
//(измена в стеке)
//Поясню:
//BSTR указывает на строку символов OLECHAR*, однако при выделении памяти через SysAllocString и др.
// аналогичные функции перед массивом символов выделяется еще DWORD с длиной строки. Таким образом,
// при работе с bstrX1 у тебя затирается стек перед bstrX1
LE>(*pPtr)->XXMethod(bstrX1, bstrX2);
//это кажется тоже не должно компилироваться
LE>delete pPtr;
LE>

LE>Так вот, если этот кусок выполняется, то при завершении программы неск. раз выскакивает "Программа выполнила недопустимую операцию...". Не подскажете-ли, где тут собака порылась?
Свой вариант:
BSTR bstrX1;
BSTR bstrX2;
try
{
    IXXPtr pPtr(__uuidof(XX);
    pPtr->XXMethod(&bstrX1, &bstrX2);
}
catch(_com_error& e)
{
    AfxMessageBox(*e.ErrorMessage());
}
//некоторая работа с полученными BSTR
// ..........

//освобождение строк
if (bstrX1) ::SysFreeString(bstrX1);
if (bstrX2) ::SysFreeString(bstrX2);
Re[2]: Падения программы при закрытии
От: Gleb Zemskov  
Дата: 13.04.03 04:35
Оценка: :)
GZ>    AfxMessageBox(*e.ErrorMessage());

Cорри ошибка при копировании, конечно же:
    AfxMessageBox(e.ErrorMessage());
Re[4]: Падения программы при закрытии
От: LEugene  
Дата: 14.04.03 04:32
Оценка:
GS>Показывай конструктор (включая FinslConstruct) IXX и код метода XXMethod.

STDMETHODIMP CXX::XXMethod(BSTR *p_bstrX1, BSTR *p_bstrX2, long *pVal)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState())

    CString szX1, szX2;
    CYYDlg dlg;
    if (dlg.GetX(szX1, szX2))
    {
        *p_bstrX1 = szX1.AllocSysString();
        *p_bstrX2 = szX2.AllocSysString();

        *pVal = 0;
    }
    else
        *pVal = -1;

    return S_OK;
}


Конструктор не трогал — он оставлен таким, каким сделал его визард. Да, класс CYYDlg — наследник CDialog, а его функция GetX делает DoModal и соответственно устанавливает значения обоих параметров.
Re[2]: Падения программы при закрытии
От: LEugene  
Дата: 14.04.03 04:37
Оценка:
GZ>Свой вариант:
GZ>
GZ>BSTR bstrX1;
GZ>BSTR bstrX2;
GZ>try
GZ>{
GZ>    IXXPtr pPtr(__uuidof(XX);
    pPtr->XXMethod(&bstrX1, &bstrX2);
GZ>}
GZ>catch(_com_error& e)
GZ>{
GZ>    AfxMessageBox(*e.ErrorMessage());
GZ>}
GZ>//некоторая работа с полученными BSTR
GZ>// ..........

GZ>//освобождение строк
GZ>if (bstrX1) ::SysFreeString(bstrX1);
GZ>if (bstrX2) ::SysFreeString(bstrX2);
GZ>



А это правильно — выделять память в одном COM-объекте, а освобождать в другом?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.