Как вызвать СОМ-объект, явно указывая Clsid и Iid?
void main(void) {
HRESULT hr;
IMyInterface *pMyInterface;
LPCLSID pclsid;
CLSIDFromProgID(L"MyProgID", pclsid);
GUID *piid;// IID of IMyInterface
piid->Data1 = ...;
piid->Data2 = ...;
piid->Data3 = ...;
piid->Data4[0] = ...;
...
piid->Data4[7] = ...;
hr = CoCreateInstance(
*pclsid,
NULL,
CLSCTX_INPROC_SERVER,
*piid,
(void **)(&pMyInterface) );
}
а как правильно?
Пытался сделать нечто подобное, но обломился:
void main(void) {
HRESULT hr;
IMyInterface *pMyInterface;
LPCLSID pclsid;
CLSIDFromProgID(L"MyProgID", pclsid);
GUID *piid;// IID of IMyInterface
piid->Data1 = ...;
piid->Data2 = ...;
piid->Data3 = ...;
piid->Data4[0] = ...;
...
piid->Data4[7] = ...;
А память под структуру кто будет выделять?
Имхо, надо
piid.Data1 = ...; // с точкой
// и т.д.
HRESULT hr = S_OK;
if(SUCCEEDED(hr = CoInitialize(NULL)))
{
hr = CoCreateInstance(
*pclsid,
NULL,
CLSCTX_INPROC_SERVER,
*piid,
(void **)(&pMyInterface) );
// Тут что-то делаем...
}
hr = CoCreateInstance(
*pclsid,
NULL,
CLSCTX_INPROC_SERVER,
*piid,
(void **)(&pMyInterface) );
}
а как правильно?
А поподробнее можно, где облом-то происходит и как выглядит?
Да, если где ошибся, извиняюсь, давно с КОМом разбирался, давно не пользовался...
А поподробнее можно, где облом-то происходит и как выглядит?
В моем варианте облом был в момент вызова CoCreateInstance(..) и выглядел как традиционный еррор с белым крестом на красном шаре: The instruction at "0x77e7a025" referenced memory at "0x994e79ae". The memory could not be "read". Click OK ... Click Cancel...
Причем старшие 3 байта "99 4e 79" совпадают с последними байтами в структуре GUID, а именно
.Data4[4] = 0xA2;
.Data4[5] = 0x79;
.Data4[6] = 0x4E;
.Data4[7] = 0x99;
А вот младший AE отличается от .Data4[4]
А твой вариант даже не компилируется - говорит
Error E2093 nat.cpp 86: 'operator*' not implemented in type '_GUID' for argument
s of the same type in function main()
Это в той строке, где *piid,
hr = CoCreateInstance(
*pclsid,
NULL,
CLSCTX_INPROC_SERVER,
*piid,
-----------------------
Теперь немного по сути.
Я решил поиграться с NAT'ом и сделать это через Windows NAT Traversal API, в котором описан соотв. интефейс.
В принципе, в *.H файле описаны CLSID и IID, которые нужны для CoCreateInstance. Однако, линкер на них говорит "unresolved external reference" и он по-своему прав, т.к. либ-файла у меня на эту библиотеку нет. Я пытался сгененить его из hnetcfg.dll, куда она входит в качестве составляющей, но борландовский тул выдал мне в LIB только первую часть - там нужных ГУИДов нету. А библиотека с NATом обозначается как hnetcfg.dll/2 и как вытащить ее в LIB я не знаю.
А твой вариант даже не компилируется - говорит
Error E2093 nat.cpp 86: 'operator*' not implemented in type '_GUID' for argument
s of the same type in function main()
Это в той строке, где *piid,
hr = CoCreateInstance(
*pclsid,
NULL,
CLSCTX_INPROC_SERVER,
*piid,
-----------------------
Я протупил: надо было звёздочи поубирать.
my_iid.Data1 = 0;
// и т.д.
HRESULT hr = S_OK;
CLSID my_clsid;
if(SUCCEEDED(hr = CoInitialize(NULL)))
{
hr = CoCreateInstance(
my_clsid,
NULL,
CLSCTX_INPROC_SERVER,
my_iid,
(void **)(&pMyInterface) );
// Тут что-то делаем...
}
Вот что MSDN по этому поводу говорит:
CoCreateInstance
Creates a single uninitialized object of the class associated with a specified CLSID. Call CoCreateInstance when you want to create only one object on the local system. To create a single object on a remote system, call CoCreateInstanceEx. To create multiple objects based on a single CLSID, refer to the CoGetClassObject function.
STDAPI CoCreateInstance(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
REFIID riid,
LPVOID * ppv
);
Parameters
rclsid
in CLSID associated with the data and code that will be used to create the object.
pUnkOuter
in If NULL, indicates that the object is not being created as part of an aggregate. If non-NULL, pointer to the aggregate object's IUnknown interface (the controlling IUnknown).
dwClsContext
in Context in which the code that manages the newly created object will run. The values are taken from the enumeration CLSCTX.
riid
in Reference to the identifier of the interface to be used to communicate with the object.
ppv
out Address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppv contains the requested interface pointer. Upon failure, *ppv contains NULL.
Return Values
S_OK
An instance of the specified object class was successfully created.
REGDB_E_CLASSNOTREG
A specified class is not registered in the registration database. Also can indicate that the type of server you requested in the CLSCTX enumeration is not registered or the values for the server types in the registry are corrupt.
CLASS_E_NOAGGREGATION
This class cannot be created as part of an aggregate.
E_NOINTERFACE
The specified class does not implement the requested interface, or the controlling IUnknown does not expose the requested interface.
Remarks
The CoCreateInstance helper function provides a convenient shortcut by connecting to the class object associated with the specified CLSID, creating an uninitialized instance, and releasing the class object. As such, it encapsulates the following functionality:
CoGetClassObject(rclsid, dwClsContext, NULL, IID_IClassFactory, &pCF);
hresult = pCF->CreateInstance(pUnkOuter, riid, ppvObj)
pCF->Release();
It is convenient to use CoCreateInstance when you need to create only a single instance of an object on the local machine. If you are creating an instance on remote machine, call CoCreateInstanceEx. When you are creating multiple instances, it is more efficient to obtain a pointer to the class object's IClassFactory interface and use its methods as needed. In the latter case, you should use the CoGetClassObject function.
In the CLSCTX enumeration, you can specify the type of server used to manage the object. The constants can be CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_LOCAL_SERVER, or any combination of these values. The constant CLSCTX_ALL is defined as the combination of all three. For more information about the use of one or a combination of these constants, refer to CLSCTX.
Requirements
Windows NT/2000/XP: Requires Windows NT 3.1 or later.
Windows 95/98: Requires Windows 95 or later.
Header: Declared in objbase.h.
Library: Use ole32.lib.
See Also
CoGetClassObject, IClassFactory::CreateInstance, CoCreateInstanceEx, CLSCTX, Instance Creation Helper Functions
Requirements
Windows NT/2000/XP: Requires Windows NT 3.1 or later.
Windows 95/98: Requires Windows 95 or later.
Header: Declared in objbase.h.
Library: Use ole32.lib.
Я протупил: надо было звёздочи поубирать.
Точно, причем фишка в убирании звездочек у обоих параметров, т.е. надо было обозвать:
CLSID my_clsid;
GUID my_iid;
а я до этого экспериментировал только со вторым. однако, спасибо.