C ++和VBA:构建一个免注册的COM DLL?

时间:2018-04-16 10:26:48

标签: c++ vba com

简而言之: 是否可以创建一个基于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;
}

0 个答案:

没有答案
相关问题