C# C2259:&x27;ATL::ccombject<;基地>';:无法实例化抽象类 我有一个功能良好的C++ DLL,它有8种方法被C语言应用程序使用。所有方法都有简单的类型参数,如“代码> int *”和“代码>浮点*/COD>,用于将信息从C++代码传递到C代码。
现在,我用一个具有参数C# C2259:&x27;ATL::ccombject<;基地>';:无法实例化抽象类 我有一个功能良好的C++ DLL,它有8种方法被C语言应用程序使用。所有方法都有简单的类型参数,如“代码> int *”和“代码>浮点*/COD>,用于将信息从C++代码传递到C代码。,c#,c++,interop,C#,C++,Interop,现在,我用一个具有参数char*的方法扩展了接口,我从Visual Studion 2012中得到了以下编译错误: 错误C2259:'ATL::CComObject':无法实例化抽象类 我附上了C、H和IDL文件。添加了方法GetError,并导致编译错误 提前感谢您的评论 激光。h: // Laser.h: Definition of the Laser class // /////////////////////////////////////////////////////////////
char*
的方法扩展了接口,我从Visual Studion 2012中得到了以下编译错误:
错误C2259:'ATL::CComObject':无法实例化抽象类
我附上了C、H和IDL文件。添加了方法GetError
,并导致编译错误
提前感谢您的评论
激光。h:
// 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_)
// 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;
}
您应该对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;
}
谢谢你,德米特里。我尝试了这个方法,但在C#中,我从封送处理程序中得到了一个“ref string”作为参数,并且放在BSTR*中的文本没有出现在引用的字符串中。对此有什么建议吗?您应该使用
SysAllocString()
,或ATL::CComBSTR
,或在GetError()
中创建一个字符串,甚至是一个空字符串。在C端,您应该使用类似stringerror;Laser.GetError(输出错误)代码>
// .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;
}