简而言之: 是否可以创建一个基于C ++的COM组件,我可以从VBA引用和使用它,而无需注册DLL(在Windows注册表中)?
长期:
我是一个COM新手,所以也许我在这里尝试做的结构不起作用或没有意义,但是:
我想创建一个可从VBA免注册使用的C ++ COM库。 所以我在VS中创建了一个C ++ ATL项目,添加了一个自定义COM类型(MyClass)并添加了一个测试方法(“AddNumbers”,获取2个长参数并返回1)。
构建此项目时,我收到错误“无法注册输出。请尝试进行每用户重定向,或者使用提升的权限从注释提示注册组件”,可能是因为我在没有管理员的情况下运行Visual Studio权限。但是,DLL构建正常,我认为它在构建之后就没有注册。
是的,所以当我在我的VBA项目中引用这个DLL(工具 - >参考 - >浏览...并添加)时,intellisesne工作,即VBA知道类型“MyClass”,知道它有一个方法“ AddNumbers“等等。 但是,它无法实例化它:
Sub test()
Dim q As MyClass
Set q = New MyClass ' This will fail: "Run-time error '429': ActiveX component can't create object"
End Sub
为什么?我是否正确地假设它可能失败,因为这个COM组件没有在机器上正确注册? 如果是这样,我可以以某种方式绕过这个吗?我已经阅读了一些关于基于.NET的免注册COM组件的信息,但我不知道这是否也有效 - 甚至是否需要?! - 适用于基于C ++的组件。
MyClass.h
// MyClass.h : Declaration of the CMyClass
#pragma once
#include "resource.h" // main symbols
#include "ATLProject4_i.h"
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif
using namespace ATL;
// CMyClass
class ATL_NO_VTABLE CMyClass :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyClass, &CLSID_MyClass>,
public IDispatchImpl<IMyClass, &IID_IMyClass, &LIBID_ATLProject4Lib, /*wMajor =*/ 0xFFFF, /*wMinor =*/ 0xFFFF>
{
public:
CMyClass()
{
}
DECLARE_REGISTRY_RESOURCEID(106)
BEGIN_COM_MAP(CMyClass)
COM_INTERFACE_ENTRY(IMyClass)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
public:
STDMETHOD(AddNumbers)(LONG Num1, LONG Num2, LONG* ReturnVal);
};
OBJECT_ENTRY_AUTO(__uuidof(MyClass), CMyClass)
MyClass.cpp
// MyClass.cpp : Implementation of CMyClass
#include "stdafx.h"
#include "MyClass.h"
// CMyClass
STDMETHODIMP CMyClass::AddNumbers(LONG Num1, LONG Num2, LONG* ReturnVal)
{
// TODO: Add your implementation code here
*ReturnVal = Num1 + Num2;
return S_OK;
}