C++ 生成器错误。 Vcl.Buttons.hpp(44):通过名称查找找到的候选者是“Vcl”

问题描述 投票:0回答:1

当我在 C++ Builder 中创建简单项目并从我的包 - EhLib 中添加组件时,我收到下一个编译错误。

[bcc32c Error] Vcl.Buttons.hpp(66): reference to 'Vcl' is ambiguous
  Vcl.Buttons.hpp(44): candidate found by name lookup is 'Vcl'
  EhLib.VCL.hpp(48): candidate found by name lookup is 'Ehlib::Vcl'

我无法找出错误的原因。

在Delphi中创建类似的项目时,没有出现错误。

我使用 Embarcadero® RAD Studio 12 版本 29.0.53982.0329

我还无法制作一个最小的项目来重现该错误,因为 EhLib 包包含相当多的文件和代码。

我在EhLib.VCL.Hpp文件中发现了如下usingnamespace语句,但是我无法删除它,因为这个文件是系统根据pas文件自动生成的。

文件 EhLib.VCL.hpp

...
    extern DELPHI_PACKAGE System::Types::TPoint __fastcall SafeGetMouseCursorPos(void);
    extern DELPHI_PACKAGE System::UnicodeString __fastcall GetEhLibGUISysInfoAsString(void);
    extern DELPHI_PACKAGE System::UnicodeString __fastcall GetEhLibFullSysInfoAsString(void);
    }   /* namespace Vcl */
    }   /* namespace Ehlib */
    #if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_EHLIB_VCL)
    using namespace Ehlib::Vcl;
    #endif
    #if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_EHLIB)
    using namespace Ehlib;
    #endif
    #pragma pack(pop)
    #pragma option pop
    
    #pragma delphiheader end.

我根本不在我的代码中使用 using 命名空间。所有usingnamespace语句都在自动生成的hpp文件中,不建议更改。

我无法添加整个源文件,因为 stackoverflow 将文本限制为 30,000 个字符,所以我只添加看起来重要的部分。

文件Unit1.cpp。我可以编辑的文件。

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "MemTableDataEh"
#pragma link "MemTableEh"
#pragma link "DBAxisGridsEh"
#pragma link "DBGridEh"
#pragma link "DBGridEhGrouping"
#pragma link "DBGridEhToolCtrls"
#pragma link "DynVarsEh"
#pragma link "EhLib.VCL"
#pragma link "GridsEh"
#pragma link "ToolCtrlsEh"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//
}
//---------------------------------------------------------------------------

文件Vcl.Buttons.hpp。我无法编辑这个文件。它是基础 VCL 库的一部分。

// CodeGear C++Builder
// Copyright (c) 1995, 2024 by Embarcadero Technologies, Inc.
// All rights reserved

// (DO NOT EDIT: machine generated header) 'Vcl.Buttons.pas' rev: 36.00 (Windows)

#ifndef Vcl_ButtonsHPP
#define Vcl_ButtonsHPP

#pragma delphiheader begin
#pragma option push
#if defined(__BORLANDC__) && !defined(__clang__)
#pragma option -w-      // All warnings off
#pragma option -Vx      // Zero-length empty class member 
#endif
#pragma pack(push,8)
#include <System.hpp>
#include <SysInit.hpp>
#include <Winapi.Windows.hpp>
#include <Winapi.Messages.hpp>
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.Graphics.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.ExtCtrls.hpp>
#include <Winapi.CommCtrl.hpp>
#include <Vcl.ImgList.hpp>
#include <Vcl.Themes.hpp>
#include <System.UITypes.hpp>
#include <System.Generics.Collections.hpp>
#include <System.SysUtils.hpp>
#include <System.Generics.Defaults.hpp>
#include <System.Types.hpp>
#include <System.Actions.hpp>
#include <Vcl.Menus.hpp>
#include <Vcl.ActnList.hpp>

//-- user supplied -----------------------------------------------------------
#ifndef _WIN64
#pragma link "dwmapi.lib"
#endif //_WIN64

...

    
};


//-- var, const, procedure ---------------------------------------------------
extern DELPHI_PACKAGE void __fastcall (*FNavigatorEnableChanged)(TBaseNavigator* Self);
extern DELPHI_PACKAGE Winapi::Windows::TRect __fastcall DrawButtonFace(Vcl::Graphics::TCanvas* Canvas, const Winapi::Windows::TRect &Client, int BevelWidth, TButtonStyle Style, bool IsRounded, bool IsDown, bool IsFocused);
}   /* namespace Buttons */
}   /* namespace Vcl */
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_VCL_BUTTONS)
using namespace Vcl::Buttons;
#endif
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_VCL)
using namespace Vcl;
#endif
#pragma pack(pop)
#pragma option pop

#pragma delphiheader end.
//-- end unit ----------------------------------------------------------------
#endif  // Vcl_ButtonsHPP

文件EhLib.VCL.hpp。我无法编辑这个文件。它是自动生成的。

// CodeGear C++Builder
// Copyright (c) 1995, 2024 by Embarcadero Technologies, Inc.
// All rights reserved

// (DO NOT EDIT: machine generated header) 'EhLib.VCL.pas' rev: 36.00 (Windows)

#ifndef EhLib_VCLHPP
#define EhLib_VCLHPP

#pragma delphiheader begin
#pragma option push
#if defined(__BORLANDC__) && !defined(__clang__)
#pragma option -w-      // All warnings off
#pragma option -Vx      // Zero-length empty class member 
#endif
#pragma pack(push,8)
#include <System.hpp>
#include <SysInit.hpp>
#include <Vcl.Forms.hpp>
#include <System.SysUtils.hpp>
#include <Data.DB.hpp>
#include <System.TypInfo.hpp>
#include <Vcl.Controls.hpp>
#include <Winapi.Messages.hpp>
#include <System.Generics.Defaults.hpp>
#include <System.Generics.Collections.hpp>
#include <System.Classes.hpp>
#include <System.RTLConsts.hpp>
#include <Winapi.Windows.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Winapi.UxTheme.hpp>
#include <System.UITypes.hpp>
#include <EhLibUtils.hpp>
#include <DBUtilsEh.hpp>
#include <Vcl.ImgList.hpp>
#include <Vcl.Graphics.hpp>
#include <Vcl.Themes.hpp>
#include <System.Variants.hpp>
#include <System.Contnrs.hpp>
#include <System.StrUtils.hpp>
#include <System.Math.hpp>
#include <System.Types.hpp>

//-- user supplied -----------------------------------------------------------

namespace Ehlib
{
namespace Vcl
{
//-- forward type declarations -----------------------------------------------
class DELPHICLASS TWinControlEh;
class DELPHICLASS TCustomControlEh;
struct TDrawTextOptionsEh;
class DELPHICLASS TFilerAccess;
class DELPHICLASS TMemoryStreamEh;
//-- type declarations -------------------------------------------------------
typedef Data::Db::TBookmark TUniBookmarkEh;

...

extern DELPHI_PACKAGE System::Variant __fastcall RefObjectToVariant(System::TObject* ARefObject);
extern DELPHI_PACKAGE System::TObject* __fastcall VariantToRefObject(const System::Variant &VarValue);
extern DELPHI_PACKAGE System::Types::TPoint __fastcall SafeGetMouseCursorPos(void);
extern DELPHI_PACKAGE System::UnicodeString __fastcall GetEhLibGUISysInfoAsString(void);
extern DELPHI_PACKAGE System::UnicodeString __fastcall GetEhLibFullSysInfoAsString(void);
}   /* namespace Vcl */
}   /* namespace Ehlib */
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_EHLIB_VCL)
using namespace Ehlib::Vcl;
#endif
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_EHLIB)
using namespace Ehlib;
#endif
#pragma pack(pop)
#pragma option pop

#pragma delphiheader end.
//-- end unit ----------------------------------------------------------------
#endif  // EhLib_VCLHPP
c++ c++builder vcl
1个回答
0
投票

默认情况下,Pascal 生成的 HPP 标头将其 C++ 命名空间带入 HPP 文件的命名空间(通常是全局范围)。 而且由于两个

#include
命名空间都在同一范围内,编译器不知道要使用哪一个,因此会出现歧义错误。
如果您仔细查看 HPP 文件,您会注意到那些 

Vcl

语句包含在预处理器块中,例如:

using namespace

为了避免歧义,您可以在 C++ 项目设置的“条件定义”部分中指定 
#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_VCL_BUTTONS) using namespace Vcl::Buttons; #endif #if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) && !defined(NO_USING_NAMESPACE_VCL) using namespace Vcl; #endif

或所需的

DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE
条件。 或者,至少,只需将
NO_USING_NAMEPACE_...
放在 C++ 代码中的相关
#define
语句上方即可。
另一种解决方法是将 

#include

添加到您的 Pascal 单位,以避免生成的 HPP 文件中出现任何

{$HPPEMIT NOUSINGNAMESPACE}
语句。
    

© www.soinside.com 2019 - 2024. All rights reserved.