Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.07.23;
Скачать: CL | DM;

Вниз

CreateComObject в Builder C++   Найти похожие ветки 

 
just   (2005-07-29 07:18) [0]

Мне нужно перевести код создания и использования COM-объекта с Delphi на Builder C++. А код такой: есть библиотека типов, в которой описывается интерфейс ISumm, затем была создана DLL (и соответсвующая ей TLB, содержащая кокласс Summ1 интерфейса ISumm). Она нормально компилится и в Builder C++. Проблема (точнее их пока две) в клиентском приложении, использующем эту DLL.
1. в файле проекта
В Delphi код такой:
program ClientProject;

uses
 Forms,
 TestUnit in "TestUnit.pas" {MainForm},
 ComObj,  
 ActiveX;

{$R *.res}

begin
 CoInitializeEx(NIL,0);  
 Application.Initialize;
 Application.CreateForm(TMainForm, MainForm);
 Application.Run;
end.

А в Builder C++:
#include <vcl.h>
#include <ActiveX.hpp>
#include <ComObj.hpp>
#include <utilcls.h>
#pragma hdrstop

USEFORM("TestUnit.cpp", MainForm);

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
       try
       {
                CoInitializeEx(0,0);  
                Application->Initialize();
                Application->CreateForm(__classid(TMainForm), &MainForm);
                Application->Run();
       }
       catch (Exception &exception)
       {
                Application->ShowException(&exception);
       }
       catch (...)
       {
                try
                {
                        throw Exception("");
                }
                catch (Exception &exception)
                {
                        Application->ShowException(&exception);
                }
       }
       return 0;
}

Вопрос такой: что является эквивалентом Nil в функции CoInitializeEx? Пока это у меня 0. Правильно ли это?
2. в самом коде
В Delphi код такой:
var
 Summ1: ISumm;
...
 Summ1:=CreateCOMObject(CLASS_Summ1) as ISumm;
...
Все, конечно, работает.
А в Builder C++:
ISumm* Summ11;
...
 Summ11*=CreateCOMObject(CLASS_Summ1);//конечно, не работает
...
Вопрос такой: как эту функцию использовать здесь? Кстати, Builder C++ вообще эту функцию не распознает, хотя она прописана в #include <ComObj.hpp>.


 
just   (2005-07-29 10:14) [1]

Ну, есть какой-нить будь аналог этой функции? Или я как-то неправильно (скорее не там) подключаю <ComObj.hpp>. Она ж там описана:
extern PACKAGE System::_di_IInterface __fastcall CreateComObject(const GUID &ClassID);


 
isasa ©   (2005-07-29 10:53) [2]

1.Почему

ISumm* Summ11; -> ISumm Summ11;

2. 0 в данном случае проходит,

HRESULT CoInitializeEx(
 void * pvReserved,  //Reserved
 DWORD dwCoInit      //COINIT value
);

в D по умолчанию используется CoInitialize, кажется.
И где CoUninitialize.
В проектах Борланд делает CoInitialize "автоматически".


 
just   (2005-07-29 11:42) [3]

2isasa ©   (29.07.05 10:53) [2]
1.
>ISumm* Summ11; -> ISumm Summ11;

если писать ISumm Summ11, то:
cannot create instance of abstract class "ISumm" //именно в этой строке
2.
>в D по умолчанию используется CoInitialize, кажется.

Нет, это не так, в Delphi, по крайней мере.


 
isasa ©   (2005-07-29 11:53) [4]

Тогда смотри описание типа
System::_di_IInterface
нет под рукой  B.

И наверно так

Summ11 = (ISumm*)CreateCOMObject(CLASS_Summ1);


 
just   (2005-07-29 12:02) [5]

Извиняюсь, не учел того (на Builder не пишу), Builder к регистру букв чувствителен. Вместо CreateCOMObject надо было CreateComObject. Теперь проблема такая: функция CreateComObject возвращает тип _di_IInterface, а мне нужен ISumm. Если в Delphi все просто:
var
Summ1: ISumm;
...
Summ1:=CreateCOMObject(CLASS_Summ1) as ISumm;
...

то в Builder"е разобраться не могу.
Пишу:
ISumm* Summ11;
...
Summ11=CreateComObject(CLSID_Summ1);
...

ошибка - несоответсвие ISumm и _di_IInterface
Пишу:
ISumm* Summ11;
...
Summ11*=CreateComObject(CLSID_Summ1);
...

ошибка - illegal use of pointer
Пишу:
_di_IInterface Summ11;
...
Summ11=CreateComObject(CLSID_Summ1);
...

все ОК, только ведь это не эзземпляр интерфейса ISumm, мне вызвать его методы (вроде того: Summ11->Print();). Короче вопрос, как конвертировать тип _di_IInterface в ISumm? Может будут другие предложения?


 
just   (2005-07-29 12:06) [6]


> isasa ©   (29.07.05 11:53) [4]
> Тогда смотри описание типа
> System::_di_IInterface
> нет под рукой  B.
>
> И наверно так
>
> Summ11 = (ISumm*)CreateCOMObject(CLASS_Summ1);

Я, конечно, и так пробовал, ошибка такая:
cannot cast from "_di_IInterface" to "ISumm"


 
isasa ©   (2005-07-29 12:09) [7]

Преобрзование типов!!!

Summ11 = (ISumm*)CreateCOMObject(CLASS_Summ1);
или
*Summ11 = (ISumm)CreateCOMObject(CLASS_Summ1);

Summ11*=CreateComObject(CLSID_Summ1);

на C -> целое по адресу Summ11 умножить на результат ф-ции CreateComObject и записать по адресу Summ11.


 
isasa ©   (2005-07-29 12:16) [8]

Посмотри хелп по сообщению.

cannot cast from "_di_IInterface" to "ISumm"

Похоже нужно использовать макросы.


 
just   (2005-07-29 12:38) [9]

Никакие варианты с * не помогают (и твои в том числе).

> isasa ©   (29.07.05 12:16) [8]
> Посмотри хелп по сообщению.
> cannot cast from "_di_IInterface" to "ISumm"

Справка пишет следующее:
A cast from type "ident1" to type "ident2" is not allowed.

In C++, you cannot cast a member function pointer to a normal function pointer.

For example:

class A {

public:
  int myex();
};
typedef int (*fp)();
test()
{
  fp myfp = (fp) &A::myex; //error
  return myfp();
}

The reason being that a class member function takes a hidden parameter, the this pointer, thus it behaves very differently than a normal function pointer.

A static member function behaves as normal function pointer and can be cast.

For example:

class A {

public:
  static int myex();
};
typedef int (*fp)();
test()
{
  fp myfp = (fp) &A::myex; //ok
  return myfp();
}

However, static member functions can only access static data members of the class.

In C

 A pointer can be cast to an integral type or to another pointer.
 An integral type can be cast to any integral, floating, or pointer type.
 A floating type can be cast to an integral or floating type.

Structures and arrays can"t be cast to or from.

You usually can"t cast from a void type.

In C++

User-defined conversions and constructors are checked for. If one can"t be found, the preceding rules apply (except for pointers to class members).

Among integral types, only a constant zero can be cast to a member pointer.

A member pointer can be cast to an integral type or to a similar member pointer.

A similar member pointer points to a data member (or to a function) if the original does. The qualifying class of the type being cast to must be the same as (or a base class of) the original.


> Похоже нужно использовать макросы.

Что ты имеешь в виду? Странно, зачем же тогда вообще функция CreateComObject в Builder C++? Смысл? вот не думал, что такие проблемы будут. И в инете ничего по этому поводу не нашел :(.


 
just   (2005-07-29 14:13) [10]

Yes!!!
Сам дошел:
IUnknown* unk;
---
unk=CreateComObject(CLSID_Summ1);
Summ11=(ISumm*)unk;
---

Все работает!
Вдруг меня осенило, что _di_IInterface - это типа делфийского IUnknown! Клево! А нигде такой информации не нашел, давно мучался с этим.
:):):)
зы. 2isasa: все равно спасибо!


 
isasa ©   (2005-07-29 21:56) [11]

Лучше поздно, чем никогда. Только пришел.
Да именно через переменную.
IUnknown не Делфи тип, а базовый COM.
Макросы в Visual Studio, динамическое и статическое преобразование типов, не знаю есть ли аналог в B.



Страницы: 1 вся ветка

Текущий архив: 2006.07.23;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.029 c
15-1150983500
QuasiLamo
2006-06-22 17:38
2006.07.23
MS Outlook - создание правил


15-1150545629
ОГО!!!
2006-06-17 16:00
2006.07.23
vs2005


15-1150180363
Мазут Береговой
2006-06-13 10:32
2006.07.23
Американцы не были на Луне... однозначно!


2-1152085498
Новинький
2006-07-05 11:44
2006.07.23
Ребята сравните несколько запросов...


15-1149995690
Black Angel
2006-06-11 07:14
2006.07.23
Не могу поставит Delphi 8