C2259:'ATL::CComObject<Base>':无法实例化抽象类

C2259: 'ATL::CComObject<Base>' : cannot instantiate abstract class

本文关键字:抽象类 gt 实例化 CComObject ATL C2259 lt Base      更新时间:2023-10-16

我有一个功能良好的C++DLL,其中包含 8 个方法,由 C# 应用程序使用。所有方法都有简单的类型参数(如 int*float*),用于将信息从C++代码传输到 C# 代码。

现在,我使用具有参数char*的方法扩展了接口,并且从Visual Studion 2012中得到以下编译错误:

错误 C2259:"ATL::CComObject":无法实例化抽象类

我附加了 C、H 和 IDL 文件。添加方法GetError并导致编译错误。

提前感谢您的评论。

激光:

// Laser.h: Definition of the Laser class
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_LASER_H__78A65319_A610_4974_86E6_F04496ADA33F__INCLUDED_)
#define AFX_LASER_H__78A65319_A610_4974_86E6_F04496ADA33F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "resource.h"       // main symbols
#include "ECLaserScanner.h"
/////////////////////////////////////////////////////////////////////////////
// Laser
class Laser : 
    public IDispatchImpl<ILaser, &IID_ILaser, &LIBID_LASERSCANNERLib>, 
    public ISupportErrorInfo,
    public CComObjectRoot,
    public CComCoClass<Laser,&CLSID_Laser>
{
public:
    Laser() {}
BEGIN_COM_MAP(Laser)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(ILaser)
    COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()
//DECLARE_NOT_AGGREGATABLE(Laser) 
// Remove the comment from the line above if you don't want your object to 
// support aggregation. 
DECLARE_REGISTRY_RESOURCEID(IDR_Laser)
// ISupportsErrorInfo
    STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
// ILaser
public:
    STDMETHOD(Construct)();
    STDMETHOD(Destruct)();
    STDMETHOD(Scan)(int* nrOfPointsNS, int* nrOfPointsEW);
    STDMETHOD(Setup)(int scanSet, int* error);
    STDMETHOD(GetData)(int indexNS, int indexEW, float* pointNS, float* pointEW, float* height);
    STDMETHOD(GetColor)(int indexNS, int indexEW, float* red, float* green, float* blue);
    STDMETHOD(GetIntensity)(int indexNS, int indexEW, float* intensity);
  STDMETHOD(GetInfo)(float* temperature, float* supplyVoltage, int* operatingTime, int* laserTime, int* motorTime);
  STDMETHOD(GetError)(char* error);
};
#endif // !defined(AFX_LASER_H__78A65319_A610_4974_86E6_F04496ADA33F__INCLUDED_)

激光.cpp:

// Laser.cpp : Implementation of CLaserScannerApp and DLL registration.
#include "stdafx.h"
#include "LaserScanner.h"
#include "Laser.h"
/////////////////////////////////////////////////////////////////////////////
//
enum ScanSetIndexType
{
    none,
    dump1,
    dump2,
    dump3,
    dump4,
    dump5,
    dump6,
    dump7,
    oven1,
    oven2,
    oven3,
    oven4,
    oven5,
    bunker,
  calibration
};
ECLaserScanner* m_scanner = 0;
STDMETHODIMP Laser::InterfaceSupportsErrorInfo(REFIID riid)
{
    static const IID* arr[] = 
    {
        &IID_ILaser,
    };
    for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
    {
        if (InlineIsEqualGUID(*arr[i],riid))
            return S_OK;
    }
    return S_FALSE;
}
STDMETHODIMP Laser::Construct()
{
  if (m_scanner)
  {
    Destruct();
  }
  m_scanner = new ECLaserScanner();
    return S_OK;
}
STDMETHODIMP Laser::Destruct()
{
  if (!m_scanner)
  {
    return -1;
  }
  delete m_scanner;
  m_scanner = 0;
    return S_OK;
}
STDMETHODIMP Laser::Setup(int set, int* error)
{
  if (!m_scanner)
  {
    return -1;
  }
  ScanSetType scanSet;
  ScanSetIndexType index = (ScanSetIndexType) set;
  scanSet.m_id = set;
  switch (index)
  {
    case calibration:
      scanSet.m_startAngleNS = 100.0;
      scanSet.m_deltaAngleNS = 0.2;
      scanSet.m_deltaCountNS = 126;
      scanSet.m_startAngleEW = 107.0;
      scanSet.m_deltaAngleEW = 0.199;
      scanSet.m_deltaCountEW = 69;
      break;
    case bunker:
      scanSet.m_startAngleNS = 100.0;
      scanSet.m_deltaAngleNS = 0.1;
      scanSet.m_deltaCountNS = 1600; // ending at 260 degrees
      scanSet.m_startAngleEW = 50.0;
      scanSet.m_deltaAngleEW = 0.2;
      scanSet.m_deltaCountEW = 350;
      break;
    case oven1: 
      scanSet.m_startAngleNS = 225.0;
      scanSet.m_deltaAngleNS = 0.2;
      scanSet.m_deltaCountNS = 77;
      scanSet.m_startAngleEW = 107.0;
      scanSet.m_deltaAngleEW = 0.199;
      scanSet.m_deltaCountEW = 68;
      break;
    case oven2: 
      scanSet.m_startAngleNS = 190.0;
      scanSet.m_deltaAngleNS = 0.2;
      scanSet.m_deltaCountNS = 126;
      scanSet.m_startAngleEW = 115.0;
      scanSet.m_deltaAngleEW = 0.199;
      scanSet.m_deltaCountEW = 75;
      break;
    case oven3: 
      scanSet.m_startAngleNS = 145.0;
      scanSet.m_deltaAngleNS = 0.2;
      scanSet.m_deltaCountNS = 127;
      scanSet.m_startAngleEW = 115.0;
      scanSet.m_deltaAngleEW = 0.199;
      scanSet.m_deltaCountEW = 75;
      break;
    case oven4: 
      scanSet.m_startAngleNS = 110.0;
      scanSet.m_deltaAngleNS = 0.2;
      scanSet.m_deltaCountNS = 126;
      scanSet.m_startAngleEW = 107.0;
      scanSet.m_deltaAngleEW = 0.199;
      scanSet.m_deltaCountEW = 69;
      break;
    case oven5: 
      scanSet.m_startAngleNS = 110.0; // was voor geheel oven 4 de startAngleNS
      scanSet.m_deltaAngleNS = 0.2;
      scanSet.m_deltaCountNS = 90;
      scanSet.m_startAngleEW = 107.0;
      scanSet.m_deltaAngleEW = 0.199;
      scanSet.m_deltaCountEW = 69;
      break;
        case dump1: 
      scanSet.m_startAngleNS = 180.0;
      scanSet.m_deltaAngleNS = 0.0;
      scanSet.m_deltaCountNS = 0;
      scanSet.m_startAngleEW = 50.0;
      scanSet.m_deltaAngleEW = 0.0;
      scanSet.m_deltaCountEW = 0;
      break;
    case dump2: 
      scanSet.m_startAngleNS = 180.0;
      scanSet.m_deltaAngleNS = 0.0;
      scanSet.m_deltaCountNS = 0;
      scanSet.m_startAngleEW = 50.0;
      scanSet.m_deltaAngleEW = 0.0;
      scanSet.m_deltaCountEW = 0;
      break;
    case dump3: 
      scanSet.m_startAngleNS = 180.0;
      scanSet.m_deltaAngleNS = 0.0;
      scanSet.m_deltaCountNS = 0;
      scanSet.m_startAngleEW = 50.0;
      scanSet.m_deltaAngleEW = 0.0;
      scanSet.m_deltaCountEW = 0;
      break;
    case dump4: 
      scanSet.m_startAngleNS = 180.0;
      scanSet.m_deltaAngleNS = 0.0;
      scanSet.m_deltaCountNS = 0;
      scanSet.m_startAngleEW = 50.0;
      scanSet.m_deltaAngleEW = 0.0;
      scanSet.m_deltaCountEW = 0;
      break;
    case dump5: 
      scanSet.m_startAngleNS = 180.0;
      scanSet.m_deltaAngleNS = 0.0;
      scanSet.m_deltaCountNS = 0;
      scanSet.m_startAngleEW = 50.0;
      scanSet.m_deltaAngleEW = 0.0;
      scanSet.m_deltaCountEW = 0;
      break;
    case dump6: 
      scanSet.m_startAngleNS = 180.0;
      scanSet.m_deltaAngleNS = 0.0;
      scanSet.m_deltaCountNS = 0;
      scanSet.m_startAngleEW = 50.0;
      scanSet.m_deltaAngleEW = 0.0;
      scanSet.m_deltaCountEW = 0;
      break;
    case dump7: 
      scanSet.m_startAngleNS = 180.0;
      scanSet.m_deltaAngleNS = 0.0;
      scanSet.m_deltaCountNS = 0;
      scanSet.m_startAngleEW = 50.0;
      scanSet.m_deltaAngleEW = 0.0;
      scanSet.m_deltaCountEW = 0;
      break;
    default:
      return -1;
  }
  *error = m_scanner->Setup(scanSet);
    return S_OK;
}
STDMETHODIMP Laser::Scan(int* nrOfPointsNS, int* nrOfPointsEW)
{
  if (!m_scanner)
  {
    return -1;
  }
  m_scanner->Scan();
  m_scanner->GetScanner()->GetDimension(nrOfPointsNS, nrOfPointsEW);
    return S_OK;
}
STDMETHODIMP Laser::GetData(int indexNS, int indexEW, float* pointNS, float* pointEW, float* height)
{
  if (!m_scanner)
  {
    return -1;
  }
  int result = m_scanner->GetData(indexNS, indexEW, pointNS, pointEW, height);
  if (result != 0)
  {
    return result;
  }
    return S_OK;
}
STDMETHODIMP Laser::GetColor(int indexNS, int indexEW, float* red, float* green, float* blue)
{
  if (!m_scanner)
  {
    return -1;
  }
  int result = m_scanner->GetColor(indexNS, indexEW, red, green, blue);
  if (result != 0)
  {
    return result;
  }
    return S_OK;
}
STDMETHODIMP Laser::GetIntensity(int indexNS, int indexEW, float* intensity)
{
  if (!m_scanner)
  {
    return -1;
  }
  int result = m_scanner->GetIntensity(indexNS, indexEW, intensity);
  if (result != 0)
  {
    return result;
  }
    return S_OK;
}
STDMETHODIMP Laser::GetInfo(float* temperature,
                            float* supplyVoltage,
                            int* operatingTime,
                            int* laserTime,
                            int* motorTime)
{
  if (!m_scanner)
  {
    return -1;
  }
  int result = m_scanner->GetInfo(temperature, supplyVoltage, operatingTime, laserTime, motorTime);
  if (result != 0)
  {
    return result;
  }
    return S_OK;
}
STDMETHODIMP Laser::GetError(char* error)
{
    error = "hallo";
    return S_OK;
}

**激光扫描仪.idl **

// LaserScanner.idl : IDL source for LaserScanner.dll
//
// This file will be processed by the MIDL tool to
// produce the type library (LaserScanner.tlb) and marshalling code.
import "oaidl.idl";
import "ocidl.idl";
    [
        object,
        uuid(1C161160-B6B4-4AE2-BF07-A14D78AF6270),
        dual,
        helpstring("ILaser Interface"),
        pointer_default(unique)
    ]
    interface ILaser : IDispatch
    {
        [id(1), helpstring("method Construct")] HRESULT Construct();
        [id(2), helpstring("method Destruct")] HRESULT Destruct();
        [id(3), helpstring("method Setup")] HRESULT Setup(int scanSet, int* errorz);
        [id(4), helpstring("method Scan")] HRESULT Scan(int* nrOfPointsNS, int* nrOfPointsEW);
        [id(5), helpstring("method GetData")] HRESULT GetData(int indexNS, int indexEW, float* pointNS, float* pointEW, float* height);
        [id(6), helpstring("method GetColor")] HRESULT GetColor(int indexNS, int indexEW, float* red, float* green, float* blue);
        [id(7), helpstring("method GetIntensity")] HRESULT GetIntensity(int indexNS, int indexEW, float* intensity);
        [id(8), helpstring("method GetInfo")] HRESULT GetInfo(float* temperature, float* supplyVoltage, int* operatingTime, int* laserTime, int* motorTime);
        [id(9), helpstring("method GetError")] HRESULT GetError(char* error);
    };
[
    uuid(3B556F88-6FEC-4A55-A7A3-8360C9103056),
    version(1.0),
    helpstring("LaserScanner 1.4 Type Library")
]
library LASERSCANNERLib
{
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");

    [
        uuid(67927D42-6C28-466F-8D83-9346A0D48F71),
        helpstring("Laser Class")
    ]
    coclass Laser
    {
        [default] interface ILaser;
    };
};

您应该在 COM 中对字符串使用 BSTR。或者,您需要为该类型的字符串创建自定义封送拆收器。

// .idl
[id(9), helpstring("method GetError")] HRESULT GetError(BSTR* error);
// .h
STDMETHOD(GetError)(BSTR* error);
// .cpp
STDMETHODIMP Laser::GetError(BSTR* pError)
{
    HRESULT hr = E_INVALIDARG;
    CComBSTR e(L"some sort of error message");
    if (pError) {
        hr = e.CopyTo(pError);
    }
    return hr;
}