Ответ 1
Вам нужно знать, какой интерфейс вы запрашиваете. Это вы получаете из спецификации продукта, из файлов заголовков SDK или можете импортировать TLB объекта COM в свой проект.
Самый простой способ - использовать # import
Я хочу программно получить идентификатор интерфейса для любого класса, чтобы передать его в CoCreateInstance. Любая помощь очень ценится!
См. "Как мне это получить" ниже:
HRESULT hResult;
CLSID ClassID;
void *pInterface;
if(!(hResult = SUCCEEDED(CoInitialize(NULL))))
{
return 1;
}
if(S_OK == CLSIDFromProgID(OLESTR("Scripting.FileSystemObject"), &ClassID))
{
hResult = CoCreateInstance(ClassID, NULL, CLSCTX_INPROC_SERVER,
<<How Do I Get This?>>, (LPVOID *)&pInterface);
}
CoUninitialize();
РЕДАКТИРОВАТЬ: Спасибо за всю помощь, кажется, отлично работает сейчас!:
HRESULT hResult;
CLSID ClassID;
IClassFactory *pClf;
void *pVdb;
if(!(hResult = SUCCEEDED(CoInitialize(NULL))))
{
return 1;
}
if(SUCCEEDED(CLSIDFromProgID(OLESTR("Scripting.FileSystemObject"), &ClassID))
{
IDispatch *pDispatch;
if(SUCCEEDED(CoCreateInstance(ClassID, NULL, CLSCTX_INPROC_SERVER,
IID_IDispatch, (void **)&pDispatch))
{
OLECHAR *sMember = L"FileExists";
DISPID idFileExists;
if(SUCCEEDED(pDispatch->GetIDsOfNames(
IID_NULL, &sMember, 1, LOCALE_SYSTEM_DEFAULT, &idFileExists))
{
unsigned int puArgErr = 0;
VARIANT VarResult;
EXCEPINFO pExcepInfo;
VariantInit(&VarResult);
VariantInit(&pExcepInfo);
DISPPARAMS pParams;
memset(&pParams, 0, sizeof(DISPPARAMS));
pParams.cArgs = 1;
VARIANT Arguments[1];
VariantInit(&Arguments[0]);
pParams.rgvarg = Arguments;
pParams.cNamedArgs = 0;
pParams.rgvarg[0].vt = VT_BSTR;
pParams.rgvarg[0].bstrVal = SysAllocString(L"C:\\Test.txt");
hResult = pDispatch->Invoke(
idFileExists,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&pParams,
&VarResult,
&pExcepInfo,
&puArgErr
);
SysFreeString(pParams.rgvarg[0].bstrVal);
printf("File Exists? %d\n", abs(VarResult.boolVal));
}
pDispatch->Release();
}
}
CoUninitialize();
Вам нужно знать, какой интерфейс вы запрашиваете. Это вы получаете из спецификации продукта, из файлов заголовков SDK или можете импортировать TLB объекта COM в свой проект.
Самый простой способ - использовать # import
Вы уже это знаете. Это будет тип вывода времени компиляции, который вы хотите сохранить в переменной pInterface
, которую вы указали.
Другими словами, какой тип интерфейса вы собираетесь обрабатывать созданный вами объект? Какие методы интерфейса вы собираетесь называть?
Тип, который вы получаете из CLSIDFromProgID
, может быть любой версией интерфейса, включая тот, который даже не существовал при компиляции вашего кода. Обычно можно предположить, что любая версия доступна во время выполнения, а также поддерживает меньшую версию, о которой вы знаете во время компиляции. Вы попросите ОС создать экземпляр последней версии, но затем вы также попросите его вернуть ссылку на интерфейс меньшей версии - тот, с которым вы знаете, как обращаться.
Функция вызывает QueryInterface
объекта для вас, используя запрошенный вами тип, например:
obj->QueryInterface(riid, pInterface);
Если у вас нет более конкретного запроса, просто используйте IUnknown
.
платформа SDK распространяется с исходным кодом утилиты OleView, t содержит довольно хороший пример для построения дерева всех возможных CLSID и их имен