Форум: "Corba";
Текущий архив: 2006.07.23;
Скачать: [xml.tar.bz2];
Вниз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 вся ветка
Форум: "Corba";
Текущий архив: 2006.07.23;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.013 c