Это мой файл IDL. IFrame является двойным интерфейсом и наследует как IDispatch, так и IUnknown.
[
object,
uuid(C5AD0517-37FC-479C-9C7A-A063B17E4A2E),
dual,
nonextensible,
pointer_default(unique)
]
interface IFrame : IDispatch{
};
[
uuid(F7D50952-4AF1-491B-B0AA-35083AEFA998),
version(1.0),
]
library bdsCOMLib
{
importlib("stdole2.tlb");
[
uuid(9C2E7E2D-A39C-4FE7-BEEB-3BF65F9D4C05)
]
coclass Frame
{
[default] interface IFrame;
};
};
И это объявление класса CFrame, которое должно реализовать IFrame:
class ATL_NO_VTABLE CFrame :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CFrame, &CLSID_Frame>,
public IDispatchImpl<IFrame, &IID_IFrame, &LIBID_bdsCOMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
CFrame()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_FRAME)
BEGIN_COM_MAP(CFrame)
COM_INTERFACE_ENTRY(IFrame)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
};
OBJECT_ENTRY_AUTO(__uuidof(Frame), CFrame)
COM-сервер регистрируется и работает нормально, когда я использую объект Frame в VBA, но с помощью ранней привязки. Я хочу использовать этот объект с VBScript, поэтому мне нужна поздняя привязка.
Но позднее связывание сделать нельзя. Я прочитал о ситуации, и кажется, что ATL (и класс IDispatchImp) выполняют всю реализацию, необходимую для IDispatch, что дает мне возможность использовать объект с инструментами автоматизации (например, VBScript).
Однако на практике скрипт выдает ошибку «Элемент Active X не может быть создан». То же самое и в VBA, когда я пытаюсь выполнить раннее связывание.
Что я делаю не так? Я использую Visual Studio 2012 в 64-разрядной версии Windows 7, но мой COM-сервер 32-разрядный (и он зарегистрирован в системе).
cscript
, убедитесь, что вы запускаете 32-разрядную версиюC:\Windows\SYSWOW64\cscript.exe
для вашего 32-разрядного COM-сервера. - person Roman R.   schedule 08.07.2014IProvideoClassIInfo
. Ваша непосредственная стратегия отладки состоит в том, чтобы поставить точку останова в конструкторе, чтобы увидеть, создан ли экземпляр вашего класса. Затем, если да, вы видите, какие интерфейсы запрашиваются до того, как произойдет сбой. Если ваш конструктор не достигнут, значит, у вас проблема с регистрацией. - person Roman R.   schedule 08.07.2014IDispatchImpl
методы и проверить, как они себя ведут. Скорее всего, вам понадобитсяSleep()
в конструкторе, чтобы у вас было время подключиться к нужному процессу. - person sharptooth   schedule 08.07.2014