Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
263 / 152 / 33
Регистрация: 29.06.2019
Сообщений: 1,538

Создание Клиента на С++ для подключения СОМ-надстройки

01.05.2025, 18:56. Показов 4519. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
может, свежим взглядом видно, почему из с++ не сортирует эта COM?
возможно, использую более позднюю версию... у меня на компе, вероятно, эта ArraySort без S
GUID прописала в header'e

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//mycom.h
#ifndef _my__dynamiclinking2_mycom_h_
#define _my__dynamiclinking2_mycom_h_
 
#include <windowsx.h>
#include <iostream>
#include <initguid.h>
/* in oleview.exe
    [
      odl,
      uuid(8465DED5-1F50-4A34-B0BD-D4379FDDE618),
      dual,
      nonextensible,
      oleautomation
    ]
    interface IVBA : IDispatch {
        [id(0x00000001), helpstring("Array sort")]
        HRESULT ArraySort(
                        [in, out] VARIANT* array_in_out, 
                        [in, optional, defaultvalue(0)] VARIANT_BOOL sort_order, 
                        [in, optional, defaultvalue(-1)] long key_1, 
                        [in, optional, defaultvalue(-1)] long key_2, 
                        [in, optional, defaultvalue(-1)] long key_3, 
                        [in, optional, defaultvalue(0)] long sort_orientation, 
                        [in, optional, defaultvalue(0)] VARIANT_BOOL delete_duplicates, 
                        [in, optional, defaultvalue(0)] VARIANT_BOOL out_array_index, 
                        [in, out, optional, defaultvalue(0)] VARIANT* index_array_out);
    };
    */
 
DEFINE_GUID( IID_IVBA,             
             0x8465ded5,0x1f50,0x4a34,0xb0,0xbd,0xd4,0x37,0x9f,0xdd,0xe6,0x18);
 
class IVBA  : public IDispatch
{
public:
    IVBA();
    virtual ~IVBA();
    STDMETHOD(ArraySort) (VARIANT*)  PURE;
};
 
#endif
Добавлено через 7 минут
сам код по примеру отсюда
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include <vector>
#include <windows.h>
#include <comdef.h>
#include <stdio.h>
 
#include <my__dynamiclinking2/mycom.h>
// #import "C:\BedvitCOMx32.dll" - with TypeLib
 
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
 
using namespace std;
 
void fillVariant(VARIANT& varIn, BSTR *srcArray, int srcArrayLen)
{
    VARIANT *variantArray = &varIn;
    VariantInit(variantArray);
 
    SAFEARRAYBOUND aDim[1]; 
    aDim[0].lLbound = 0; 
    aDim[0].cElements = srcArrayLen;
 
    SAFEARRAY* sa = SafeArrayCreate(VT_BSTR, 1, aDim);
    if (sa)
    {    
        BSTR* dwArray = NULL;
        SafeArrayAccessData(sa, (void**)&dwArray);
 
        for(int i = 0; i < srcArrayLen; i++)
        {
            // note: passing ownership, NOT making a copy
            dwArray[i] = srcArray[i];
            std::wcout << dwArray[i] << endl;
        }
 
        SafeArrayUnaccessData(sa);
 
        variantArray->vt = VT_ARRAY|VT_BSTR;
        variantArray->parray = sa;
    }
}
 
BSTR foo(const char* s) {
  return _bstr_t(s).Detach();
}
 
int main( int argc, char *argv[] )  {
   cout << "Initializing COM" << endl;
 
   if ( FAILED( CoInitialize( NULL )))
   {
      cout << "Unable to initialize COM" << endl;
      return -1;
   }
 
   char* szProgID = "BedvitCOM.VBA";
   WCHAR  szWideProgID[128];
   CLSID  clsid;
   long lLen = MultiByteToWideChar( CP_ACP,
                        0,
                        szProgID,
                        strlen( szProgID ),
                        szWideProgID,
                        sizeof( szWideProgID ) );
 
   szWideProgID[ lLen ] = '\0';
   HRESULT hr = ::CLSIDFromProgID( szWideProgID, &clsid );
   if ( FAILED( hr ))
   {
      cout.setf( ios::hex, ios::basefield );
      cout << "Unable to get CLSID from ProgID. HR = " << hr << endl;
      return -1;
   }
//////
// https://www.rsdn.org/article/com/introcom.xml
    
   IClassFactory* pCF;
   // Получить фабрику классов для класса Math
   hr = CoGetClassObject( clsid,
                          CLSCTX_INPROC,
                          NULL,
                          IID_IClassFactory,
                          (void**) &pCF );
   if ( FAILED( hr ))
   {
      cout.setf( ios::hex, ios::basefield );
      cout << "Failed to GetClassObject server instance. HR = " << hr << endl;
      return -1;
   }
 
   // с помощью фабрики классов создать экземпляр
   // компонента и получить интерфейс IUnknown.
   IUnknown* pUnk;
   hr = pCF->CreateInstance( NULL, IID_IUnknown, (void**) &pUnk );
 
   // Release the class factory
   pCF->Release();
 
   if ( FAILED( hr ))
   {
      cout.setf( ios::hex, ios::basefield );
      cout << "Failed to create server instance. HR = " << hr << endl;
      return -1;
   }
 
   cout << "Instance created" << endl;
 
/////// 
    vector<char*> v;
    v={ "11", "1", "2", "8", "7" };
    
    BSTR *theArray = new BSTR[5];
      
    auto it { v.begin() };  // получаем итератор
    int i=0;
    //while(it!= v.end())    // пока не дойдем до конца
    for(auto it{begin(v)}; it != end(v); it++ )
    {
        
        theArray[i] = foo(*it);
        //++iter;
        ++i;
    }
 
    VARIANT vArray;
    fillVariant(vArray, theArray, 5);
////
    
   IVBA* pVBA = NULL;
   hr = pUnk->QueryInterface( IID_IVBA, (LPVOID*)&pVBA );
   pUnk->Release();
   if ( FAILED( hr ))
   {
      cout << "QueryInterface() for IVBA failed" << endl;
      return -1;
   }
  
/////
   pVBA->ArraySort( &vArray );      // [in, out]   
///// read vArray
 
    LPCWSTR pValsOut;   
    hr = SafeArrayAccessData(vArray.parray, (void **)&pValsOut); // direct access to SA memory
    if (SUCCEEDED(hr))
    {
      long lowerBound, upperBound;  // get array bounds
      SafeArrayGetLBound(vArray.parray, 1 , &lowerBound);
      SafeArrayGetUBound(vArray.parray, 1, &upperBound);
     
      long cnt_elements = upperBound - lowerBound + 1; 
      
      long ix=0;      
      for (long i = 0; i < cnt_elements; ++i)  // iterate through returned values
        {  
            LPCWSTR lVar;
            hr= SafeArrayGetElement(vArray.parray, &ix, &lVar); 
            wcout << lVar << endl;
            ix++;
        }
        
      //for(auto& it : Var.parray) cout << "el. " << pVals[i] << endl;      
                
      SafeArrayUnaccessData(vArray.parray);
    }
    
    // don't forget to free memory when done!
    // note: the VARIANT owns the BSTRs, so DON'T free them!
    VariantClear(&vArray);
    delete[] theArray;
    
/////
   cout << "Releasing instance" << endl;
   pVBA->Release();
 
   cout << "Shuting down COM" << endl;
   CoUninitialize();
 
   return 0;
}
видимо как-то не так передаю variantArray, но не хочется связываться с IDispatch, как здесь или здесь -- т.к. вроде по GUID и CLSID и так должен вызвать метод ArraySort интерфейса IVBA. Может кто-нибудь видит проблему - в передаче массива? или в объявлении в header'e?

принтует
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Initializing COM
Instance created
11
1
2
8
7
11
1
2
8
7
Releasing instance
Shuting down COM
- т.е. не сортирует
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
01.05.2025, 18:56
Ответы с готовыми решениями:

QTcpServer - отправка сообщения нужному клиенту, или сообщение клиенту о подключении "его" устройства
Добрый день. Опять я. Опять проблема :). Вот теперь возникла другая беда: в моей системе...

Надстройка для Microsoft Office "Склонение слов"
Объясню ситуацию: дали задание на диплом написать надстройку в пакет офиса &quot;склонения слов&quot;. Язык...

Можно ли в билдере создавать надстройки для пакета Майкрософт
Всем привет. У меня вопрос (может и глупый): можно ли в билдере создавать надстройки для пакета...

35
263 / 152 / 33
Регистрация: 29.06.2019
Сообщений: 1,538
13.05.2025, 17:28  [ТС]
Студворк — интернет-сервис помощи студентам
P.S. сейчас буду разбираться... а если выдаёт "недостаточно памяти для завершения операции" (пока так на моём коде, не вашем) -- видела где-то, что это как-то связано с неправильным заполнением bstr'ов -- не могу найти точно предостережение как делать чтобы такого не было... не поясните как обычно справляться с такой ошибкой при работе с bstr'ами и в чём её суть?

Добавлено через 5 минут
Цитата Сообщение от bedvit Посмотреть сообщение
Замените функцию RunComNotATL из 12 сообщения.
не нравится ему _variant_t disp(pBedvitComVBADisp); : error C2668: '_variant_t::_variant_t': ambiguous call to overloaded function... как и в предыдущий раз

Добавлено через 2 минуты
и в мой L"ArraySort" не заходит через Invoke - значит, действительно, что-то у меня с сервером... обновляться не люблю, когда всё в vba работает... там не помню по 4м или 5ти ключам мне нужна была сортировка -- вобщем придётся лезть в рабочий код, чтобы обновление делать без сюрпризов
0
 Аватар для bedvit
1210 / 261 / 22
Регистрация: 20.05.2016
Сообщений: 1,147
Записей в блоге: 22
13.05.2025, 17:37
JeyCi, вы мой код запускаете?
Попробуйте так:
C++
1
_variant_t disp(pBedvitComVBADisp.GetInterfacePtr());
1
263 / 152 / 33
Регистрация: 29.06.2019
Сообщений: 1,538
13.05.2025, 17:52  [ТС]
arr[i][0]= _bstr_t(vec.at(i).data()).Detach() ; в моём коде даёт
error C2440: '=': cannot convert from 'BSTR' to 'OLECHAR'

Добавлено через 7 минут
Цитата Сообщение от bedvit Посмотреть сообщение
GetInterfacePtr()
в вашем коде теперь не входит в обработчик (в Debug по break-point'ам)
C++
1
2
3
4
5
6
    hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_NEUTRAL, autoType, &dp, pvResult, NULL, NULL);// Make the call!
    if (FAILED(hr)) {
        va_end(marker);
        delete[] pArgs;
        return hr;
    }
и просто завершает код без каких-либо уведомлений... попробую отпринтовать result
0
 Аватар для bedvit
1210 / 261 / 22
Регистрация: 20.05.2016
Сообщений: 1,147
Записей в блоге: 22
13.05.2025, 17:52
JeyCi, отложите ваш код и пользуйтесь моим. Все три варианта, которые я написал рабочие. В третьем варианте функция, которую можно добавить или заменить ей функцию из второго варианта. Напишите, что не работает у вас в моем варианте, без внесения туда посторонннего кода?
0
263 / 152 / 33
Регистрация: 29.06.2019
Сообщений: 1,538
13.05.2025, 18:24  [ТС]
Цитата Сообщение от JeyCi Посмотреть сообщение
попробую отпринтовать result
отпринтовала - сортирует - без обновления сервера
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     std::cout  <<  "pvResult" << std::endl;
    BSTR* resarr = NULL;
    hr = SafeArrayAccessData(array.parray, (void HUGEP**) & resarr);//открываем массив
    if (FAILED(hr)) {
        return hr;
    }
    {
        for (long i = 0; i < 3; i++){
            std::wcout  <<  resarr[i] << std::endl; 
        }
    }
    hr = SafeArrayUnaccessData(array.parray); //закрываем массив
    if (FAILED(hr)) {
        return hr;
    }
Спасибо!

Добавлено через 12 минут
но принтует сортированный именно array, а не result - ну и ладно...
0
 Аватар для bedvit
1210 / 261 / 22
Регистрация: 20.05.2016
Сообщений: 1,147
Записей в блоге: 22
13.05.2025, 18:28
Так и должно быть. Этот метод сортирует массив на месте, а не выдает новый в виде result. В VBA разве по другому?
0
263 / 152 / 33
Регистрация: 29.06.2019
Сообщений: 1,538
13.05.2025, 18:39  [ТС]
тоже так подумала... (в начале ветки ещё сомневалась, зачем result параметром в Invoke в данной ситуации)
0
 Аватар для bedvit
1210 / 261 / 22
Регистрация: 20.05.2016
Сообщений: 1,147
Записей в блоге: 22
13.05.2025, 18:53
Result здесь не нужен для получения результата, см. подробнее ArraySortS

Добавлено через 6 минут
Result возвращает значения, когда [out, retval] в параметрах метода. Проверь на других методах.

Добавлено через 2 минуты
К примеру на этом. Можно прям этот же массив. Замени метод "ArraySort" на "VariantSerialization".
0
 Аватар для bedvit
1210 / 261 / 22
Регистрация: 20.05.2016
Сообщений: 1,147
Записей в блоге: 22
14.05.2025, 10:20
Или лучше на "VariantCopy"
0
263 / 152 / 33
Регистрация: 29.06.2019
Сообщений: 1,538
15.05.2025, 10:12  [ТС]
только вопрос остался... по выше указанному работающему коду не получается подконнектить мою старенькую откомпилированную на Borland COM с методом здесь под спойлером -- возможно ли это в принципе (там вроде для 1d-dim делала) -- сервер откомпилированный на Borland использовать в С/С++ клиенте, компилируумом на VSBT - наверно, нет?
0
 Аватар для bedvit
1210 / 261 / 22
Регистрация: 20.05.2016
Сообщений: 1,147
Записей в блоге: 22
15.05.2025, 10:59
JeyCi, она зарегистрированна в реестре? Вы с ней работаете в других языках? К пример в VBA?
0
263 / 152 / 33
Регистрация: 29.06.2019
Сообщений: 1,538
15.05.2025, 12:00  [ТС]
Зарегистрирована как myEntry.myVBA - (по regedit), не использую, тогда только тестила - она работала, насколько помню. Чисто по коду - массив SafeArray, обёрнутый таким же макаром в VARIANT BYREF, - пройдёт в неё? - пока в hr=Invoke() - crash'ится... Или мне надо снова тестовые примеры для себя собирать и тестить. Просто не хочется терять время, если на самом деле проблема в разных компиляторах...
Вложения
Тип файла: zip myEntry.zip (289.0 Кб, 3 просмотров)
0
 Аватар для bedvit
1210 / 261 / 22
Регистрация: 20.05.2016
Сообщений: 1,147
Записей в блоге: 22
15.05.2025, 12:03
При чем здесь компиляторы? Если ваша СОМ-библиотека зарегистрирована в реестре и работала в VBA, она будет работать и в С++.
1
263 / 152 / 33
Регистрация: 29.06.2019
Сообщений: 1,538
15.05.2025, 14:12  [ТС]
пока выложу свой упрощённый код на вашу COM - работает
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include <iostream>
#include <string>
#include <vector>
  
  //COM
#include "comdef.h"
#include "oleacc.h"
 
void fillVariant(VARIANT& varIn, BSTR *srcArray, int srcArrayLen)
{
    VARIANT *variantArray = &varIn;
    VariantInit(variantArray);
 
    SAFEARRAYBOUND aDim[1]; 
    aDim[0].lLbound = 0; 
    aDim[0].cElements = srcArrayLen;
 
    SAFEARRAY* sa = SafeArrayCreate(VT_BSTR, 1, aDim);
    if (sa)
    {    
        BSTR* dwArray = NULL;
        SafeArrayAccessData(sa, (void**)&dwArray);
 
        for(int i = 0; i < srcArrayLen; i++)
        {
            // note: passing ownership, NOT making a copy
            dwArray[i] = srcArray[i];
            std::wcout << dwArray[i] << std::endl;
        }
 
        SafeArrayUnaccessData(sa);
 
        variantArray->vt = VT_ARRAY|VT_BSTR;
        variantArray->parray = sa;
    }
}
 
 
HRESULT RunCom()
{
    IDispatchPtr    pBedvitComVBADisp = NULL;
    HRESULT hr = 0;
    GUID guid;
    hr = IIDFromString(L"{7a65494f-2a91-415c-9ff6-38f6611675ce}", &guid);   //IVBA
    if (FAILED(hr)) { 
        return hr;
    }
    hr = CoCreateInstance(guid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&pBedvitComVBADisp);
    if (FAILED(hr)) { 
        return hr;
    }
    
    const wchar_t* ptName = L"ArraySort";    
    DISPPARAMS dp = { NULL, NULL, 0, 0 };// Variables used...
    DISPID dispidNamed = DISPID_PROPERTYPUT;
    DISPID dispID;
    hr = pBedvitComVBADisp->GetIDsOfNames(IID_NULL, (LPOLESTR*)&ptName, 1, LOCALE_NEUTRAL, &dispID);// Get DISPID for name passed...
    if (FAILED(hr)) {
        return hr;
    } 
 
    ///////////////////////////////////////////////////////////
    //переменные, создаем массив
    //ATL::CComVariant result, disp(pBedvitComVBADisp), array;
    // _variant_t vArray, result
    _variant_t disp(pBedvitComVBADisp.GetInterfacePtr() ); // disp.pdispVal
    
    VARIANT vArray; 
    VariantInit(&vArray);
    vArray.vt = VT_ARRAY | VT_BSTR;
    
    //SAFEARRAY* safeArr;
    SAFEARRAYBOUND sab[2];
        sab[0].lLbound = 0; sab[0].cElements = 3;   //i
        vArray.parray = SafeArrayCreate(VT_BSTR, 1, sab);
        if (!vArray.parray) {
            return E_POINTER;
        }
    
    //заполним массив 
    std::cout << "psaIn" << std::endl;    
    std::vector<std::wstring> vec{L"Obj", L"Rel", L"Mapping"};    
    BSTR *theArray = new BSTR[5];
 
    for(long i=0; i<3; i++ )
    {
        theArray[i] = _bstr_t(vec.at(i).c_str()).Detach() ;
    }
    // 1-dim
    fillVariant(vArray, theArray, 3);
 
    ///////////////////   
        // make sure the array is holding ARRAY value
        std::cout << "\n" << std::endl;
    
    if (vArray.parray && VT_ARRAY) std::cout << "saveArray ISARRAY" << std::endl;
    if (V_ISARRAY(&vArray)) std::cout << "&vArray ISARRAY" << std::endl;
    
    ///////////////////оборачиваем массив в VT_BYREF, 
        // что бы получить результат из метода [in, out]
    VARIANT pvarArray;
    VariantInit(&pvarArray);
    pvarArray.vt = VT_VARIANT | VT_BYREF;       
 
    pvarArray.pvarVal = &vArray;  
    if (V_ARRAYREF(pvarArray.pvarVal)) std::cout << "&pvarArray ISARRAYREF" << std::endl;       
                            
    //////////////////////////////// DISPPARAMS
    dp.rgvarg = &pvarArray;
    dp.cArgs = 1;
      
    ///////////////////////////////// сортируем
    // _variant_t varResult;
 
    VARIANT pvResult;
    VariantInit(&pvResult);
    pvResult.vt = VT_VARIANT | VT_BYREF;    
    
    EXCEPINFO excepinfo;    //struct with m_BSTR that is OLECHAR
    memset(&excepinfo, 0, sizeof(excepinfo));
    UINT nArgErr = (UINT)-1;
    
     hr = disp.pdispVal->Invoke(dispID, IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, &pvResult, &excepinfo, &nArgErr);// Make the call!
    if (FAILED(hr)) {
        std::cout << "err Invoke" << std::endl;
        MessageBoxW(NULL, _com_error(hr).ErrorMessage(), excepinfo.bstrDescription, MB_ICONERROR | MB_TOPMOST);
        return hr;
    }
 
    //////////////////////////////// RES
    std::cout  <<  "\n psaOut - vArray.parray:" << std::endl;
    BSTR* resarr = NULL;
    hr = SafeArrayAccessData(vArray.parray, (void HUGEP**) & resarr);//открываем массив
    if (FAILED(hr)) {
        return hr;
    }
    {
        for (long i = 0; i < 3; i++){
            std::wcout  <<  resarr[i] << std::endl; 
        }
    }
    hr = SafeArrayUnaccessData(vArray.parray); //закрываем массив
    if (FAILED(hr)) {   return hr;  }
 
    VariantClear(&pvarArray);
    VariantClear(&vArray);
    VariantClear(&pvResult);
    
    return 0;
}
 
  
int main()
{
    HRESULT hr = S_OK;
    hr = OleInitialize(NULL);
    if (FAILED(hr)) {
        printf("Failed to init COM.");
        return -1;
    }
    if (FAILED(hr)) {
        MessageBoxW(NULL, _com_error(hr).ErrorMessage(), L"Error", MB_ICONERROR | MB_TOPMOST);
        return hr;
    }
    hr = RunCom();
    if (FAILED(hr)) {
        MessageBoxW(NULL, _com_error(hr).ErrorMessage(), L"Error", MB_ICONERROR | MB_TOPMOST);
    }
    OleUninitialize();
    return hr;
}

на TheIDE, которой пользуюсь (win32-версия), пока не могу проверить утечки памяти и висячие указатели и ссылки (особенно при передаче в / возвращении из fillVariant) -- CRT в ней ещё не пробовала... если, кто увидит memory leaks или dangling pointers, которые не заметила - поправки принимаются...
0
263 / 152 / 33
Регистрация: 29.06.2019
Сообщений: 1,538
18.05.2025, 21:06  [ТС]
Цитата Сообщение от bedvit Посмотреть сообщение
При чем здесь компиляторы?
точно, это же про mingw и MSVC
Mixing compilers is tricky and prone to issues.

In some very simple cases it may work, but there are definitely a number of cases where you will run in to issues, for example:
  • if the different components use different runtime libraries
  • if memory management is being mixed (e.g. forget about freeing memory allocated with malloc() in MSVC using free() in MinGW)
  • when using exception handling in C++
My advice to do it all with the same compiler (and even the same version of this compiler).
и ABI может быть разный (Application Binary Interface) для них, вероятно... (как и в сравнении с Borland-овским компилятором)

Добавлено через 2 часа 29 минут
висячий указатель - описание здесь - в части кода:
C++
1
2
3
4
5
if (cmd==DISPATCH_PROPERTYPUT) {
    DISPID dispidNamed=DISPID_PROPERTYPUT;   /* <--- PROBLEM LINE here */
    dispParams.cNamedArgs=1;
    dispParams.rgdispidNamedArgs=&dispidNamed;
}
0
263 / 152 / 33
Регистрация: 29.06.2019
Сообщений: 1,538
30.05.2025, 11:52  [ТС]
Цитата Сообщение от bedvit Посмотреть сообщение
Result возвращает значения, когда [out, retval] в параметрах метода.
на InStr
- interface in oleview.exe in IVBA:
Code
1
2
3
4
5
6
[id(0x00000004), helpstring("Returns the position of the first occurrence of one string within another")]
HRESULT InStr(
                [in] BSTR StringIn, 
                [in] BSTR StringFindin, 
                [optional, defaultvalue(1)] long Start, 
                [out, retval] long* pVal);
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
 
  //COM
#include "comdef.h"
#include "oleacc.h"
 
 
HRESULT RunCom()
{
    IDispatchPtr    pBedvitComVBADisp = NULL;
    HRESULT hr = 0;
    GUID guid;
    hr = IIDFromString(L"{7a65494f-2a91-415c-9ff6-38f6611675ce}", &guid);   //IVBA
    if (FAILED(hr)) { 
        return hr;
    }
    hr = CoCreateInstance(guid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&pBedvitComVBADisp);
    if (FAILED(hr)) { 
        return hr;
    }
    
    const wchar_t* ptName = L"InStr";  
 
    DISPID dispidNamed = DISPID_PROPERTYPUT;
    DISPID dispID;
    hr = pBedvitComVBADisp->GetIDsOfNames(IID_NULL, (LPOLESTR*)&ptName, 1, LOCALE_NEUTRAL, &dispID );// Get DISPID for name passed...
    if (FAILED(hr)) {
        return hr;
    } 
    ////////////////////////////////// dp  
    
    _bstr_t StringIn(L"tofind");
    _bstr_t StringFindin(L"in"); 
    // IN REVERSED ORDER
    _variant_t pvars[2];
     pvars[0]= StringFindin;
     pvars[1]= StringIn;
     
    DISPPARAMS dp = { pvars, NULL, 2, 0 };// Variables used...
         
    /////////////////////////////////  varResult;
 
    VARIANT pvResult;
    VariantInit(&pvResult);
    pvResult.vt = VT_I4;    
    
    EXCEPINFO excepinfo;    //struct with m_BSTR that is OLECHAR
    memset(&excepinfo, 0, sizeof(excepinfo));
    UINT nArgErr = (UINT)-1;
    
    _variant_t disp(pBedvitComVBADisp.GetInterfacePtr() ); // disp.pdispVal
    
     hr = disp.pdispVal->Invoke(dispID, IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, &pvResult, &excepinfo, &nArgErr);// Make the call!
    if (FAILED(hr)) {
        std::cout << "err Invoke" << std::endl;
        MessageBoxW(NULL, _com_error(hr).ErrorMessage(), excepinfo.bstrDescription, MB_ICONERROR | MB_TOPMOST);
        return hr;
    }
    std::cout  <<  "\n res:" << pvResult.lVal << std::endl;
    VariantClear(&pvResult);
    
    return 0;
}
 
  
int main()
{
    HRESULT hr = S_OK;
    hr = OleInitialize(NULL);
    if (FAILED(hr)) {
        printf("Failed to init COM.");
        return -1;
    }
    if (FAILED(hr)) {
        MessageBoxW(NULL, _com_error(hr).ErrorMessage(), L"Error", MB_ICONERROR | MB_TOPMOST);
        return hr;
    }
    hr = RunCom();
    if (FAILED(hr)) {
        MessageBoxW(NULL, _com_error(hr).ErrorMessage(), L"Error", MB_ICONERROR | MB_TOPMOST);
    }
    OleUninitialize();
    return hr;
}
p.s. VarEnum, SafeArrayGetVartype (SAFEARRAY * pSA, VARTYPE * pVarType); returns VARENUM
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
30.05.2025, 11:52
Помогаю со студенческими работами здесь

Разрешение IE автоматически запускать надстройки
Доброго времени! Подскажите, как реализовать на Builder, чтобы IE автоматически запускал все...

Не работают функции 64 бит библиотеки в надстройке Эксель 2013
Имеется DLL: одна для 32 бит и одна для 64 бит h-файл...

Накапливание памяти при работе надстройки xll для excel
Нужно произвести несложные вычисления в столбце Excel range_in и вывести в другой столбец. Все...

Qt + надстройка Excel
Добрый день, уважаемые посетители форума! Задача в следующем. Из текстовой формы в приложении Qt...

Реализация чата Клиент - Клиент (сокеты)
Разобрался с созданием сокетов: инициализация, создание(ну или не разобрался =(( ). Не понял суть...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
36
Ответ Создать тему
Новые блоги и статьи
[golang] Breadth-First Search
alhaos 19.05.2026
BFS (Breadth-First Search) — это базовый алгоритм обхода графа в ширину, который поуровнево исследует все связанные вершины. Он начинает с выбранной точки и проверяет всех соседей, прежде чем. . .
[golang] Алгоритм «Хак Госпера»
alhaos 17.05.2026
Алгоритм «Хак Госпера» Хак Госпера (Gosper's Hack) — алгоритм нахождения следующего по величине числа с тем же количеством установленных бит. Придуман Биллом Госпером в 1970-х, опубликован в. . .
Рисование бинарного древа до 6-го колена на js, svg.
russiannick 17.05.2026
<svg width="335" height="240" viewBox="0 0 335 240" fill="#e5e1bb"> <style> <!]> </ style> <g id="bush"> </ g> </ svg> function fn(){ let rost;/ / высота древа let xx=165,yy=210,w=256;
FSharp: interface of module
DevAlt 16.05.2026
Интерфейс модуля F# позволяет управлять доступностью членов, содержащихся в реализации модуля. По-умолчанию все члены модуля доступны: module Foo let x = 10 let boo () = printfn "boo" . . .
Хитросплетение родственных связей пантеона греческих богов.
russiannick 14.05.2026
Однооконник, позволяющий узреть и изучить отдельных героев древней Греции. <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible". . .
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов. import "math" func angleClock(hour int, minutes int) float64 { . . .
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru