Unresolved external linker error in C++Builder - c++builder

I am new to C++ Builder. I am translating a Delphi project into C++. I have translated some of the Delphi code into C++ and it compiles fine in C++Builder, but I get an error:
Unresolved external ColorClasses::TColorList:: referenced from ...
when I use the TColorList constructor in my MainForm in this way:
ColorClasses::TColorList *cl;
cl = new ColorClasses::TColorList();
The TColorList constructor is defined as follows in file ColorClasses.cpp:
__fastcall ColorClasses::TColorList::TColorList() : TColorClass()
{
fcolor_list = new TList();
}
The TColorList class is declared as follows in file ColorClasses.h:
class DELPHICLASS TColorList;
class PASCALIMPLEMENTATION TColorList : public TColorClass
{
private:
TList* fcolor_list;
public:
__fastcall TColorList();
virtual __fastcall ~TColorList();
};
I have searched the StackOverflow site for similar questions relevant to C++Builder, but I can't find one specific to my problem.

The problem seems to resolve itself if I remove the keywords DELPHICLASS and PASCALIMPLEMENTATION.

Related

Can I use Googlemock mock objects in unit tests with C++Builder?

Googlemock can help build mock classes with which it is possible to detect if one method calls another method and with what parameters, and influence the behaviour of the called method.
E.g., to test that method a() in class UnderTest actually calls method b()
class UnderTest {
public:
/// Method a() calls method b().
virtual void a() {b();}
/// Method b() does nothing.
virtual void b() {}
};
one can write a mock class which overwrites method b()
class UnderTestMock : public UnderTest {
public:
MOCK_METHOD0(b, void());
};
and test if the method b() is actually called after calling method a():
TEST(UnderTest, aCallsB) {
UnderTestMock mock;
EXPECT_CALL(mock, b());
mock.a();
}
Can I use Googlemock like this with C++Builder 11.2?
No, at the moment it is not possible to use Googlemock like this with C++Builder 11.2.
The Googletest project (which includes Googlemock) itself has removed all support for C++Builder in 2019. Embarcadero has since published their own patched version of Googletest in a GetIt package, which includes project files to build Googletest and Googlemock and some usage examples.
The Googlemock-related project files are all somewhat broken, e.g. the gmock.cbproj file inserts a source file into the gmock.a library that performs some unrelated tests on Googletest. These project file errors can all be fixed easily by removing source files from the projects that do not belong there and rebuild.
However, after fixing the gmock.cbproj project file, it turns out that the main feature of Googlemock, the EXPECT_CALL() macro, is not supported by C++Builder 11.2:
This is a simple source file which puts the code pieces from the question together, adds a main function and the required includes:
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
class UnderTest {
public:
/// Method a() calls method b().
virtual void a() {b();}
/// Method b() does nothing.
virtual void b() {}
};
class UnderTestMock : public UnderTest {
public:
MOCK_METHOD0(b, void());
};
TEST(UnderTest, aCallsB) {
UnderTestMock mock;
EXPECT_CALL(mock, b());
mock.a();
}
This sample works fine with Googlemock with other compilers (at most, tchar, _tmain need to be replaced with char, main), however, with C++Builder, some required features are missing from either the compiler or from the C++ standard library. The error message when compiling with C++Builder's clang-based 64-bit compiler is
Build FAILED.
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-nice-strict.h(134,6): C++ warning : __declspec attribute 'empty_bases' is not supported
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-nice-strict.h(174,6): C++ warning : __declspec attribute 'empty_bases' is not supported
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-nice-strict.h(215,6): C++ warning : __declspec attribute 'empty_bases' is not supported
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\type_traits(2686,1): C++ error : no matching function for call to 'invoke'
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\functional(216,10): C++ error : > in instantiation of function template specialization 'std::_Invoke_ret<void, testing::internal::DoDefaultAction &>' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\functional(165,2): C++ error : > in instantiation of member function 'std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void>::_Do_call' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\xmemory0(704,23): C++ error : > in instantiation of function template specialization 'std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void>::_Func_impl<testing::internal::DoDefaultAction, const std::allocator<int> &>' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\xmemory0(845,6): C++ error : > in instantiation of function template specialization 'std::allocator<std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void> >::construct<std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void>, testing::internal::DoDefaultAction, const std::allocator<int> &>' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\xmemory0(994,13): C++ error : > in instantiation of function template specialization 'std::allocator_traits<std::allocator<std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void> > >::construct<std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void>, testing::internal::DoDefaultAction, const std::allocator<int> &>' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\functional(376,6): C++ error : > (skipping 6 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-actions.h(470,4): C++ error : > in instantiation of function template specialization 'testing::Action<void ()>::Init<testing::internal::DoDefaultAction>' requested here
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-spec-builders.h(909,8): C++ error : > in instantiation of function template specialization 'testing::Action<void ()>::Action<testing::internal::DoDefaultAction, void>' requested here
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-spec-builders.h(1629,12): C++ error : > in instantiation of member function 'testing::internal::TypedExpectation<void ()>::TypedExpectation' requested here
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-spec-builders.h(1284,29): C++ error : > in instantiation of member function 'testing::internal::FunctionMocker<void ()>::AddNewExpectation' requested here
C:\Users\...\Documents\Embarcadero\Studio\Projects\gmocktest\main.cpp(26,2): C++ error : > in instantiation of member function 'testing::internal::MockSpec<void ()>::InternalExpectedAt' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\type_traits(2664,6): C++ error : > candidate template ignored: substitution failure [with _Callable = testing::internal::DoDefaultAction &, _Types = <>]: no matching function for call to '_Call'
3 Warning(s)
13 Error(s)
The two example projects included in the GetIt package for Googlemock hint that some isolated aspects of Googlemock may be working, like at least one Googlemock matcher works inside the EXPECT_THAT() macro, but none of the examples compiled by the GetIt package make use of the main feature of Googlemock, the EXPECT_CALL() macro.

using Helpintfs::IHelpSystem gives an error 'abstract class' in C++Builder

I am using C++Builder and working with sample Delphi code for calling a new help file system called eViewer. When I convert the Delphi Procedure below the variable IHelpSystem is giving the error: variable type 'System::Helpintfs::IHelpSystem' is an abstract class. The error text is below. How can I use the variable IHelpSystem and the function GetHelpSystem in C++Builder?
//Original Delphi
procedure TFrmHelpViewerMain.btnShowTopicClick(Sender: TObject);
var
HelpSystem: IHelpSystem;
begin
GetHelpSystem(HelpSystem);
if assigned(HelpSystem) then
HelpSystem.ShowTopicHelp('topic3', Application.HelpFile);
end;
//My C++Builder code
#include <System.HelpIntfs.hpp>
void __fastcall TForm99::btnShowTopicClick(TObject *Sender)
{
IHelpSystem HelpSystem; //<< Error Here
GetHelpSystem(HelpSystem);
if( Assigned(HelpSystem) ){
HelpSystem->ShowTopicHelp("topic3", Application->HelpFile);
}
}
[bcc64 Error] CBtest_Unit1.cpp(97): variable type 'System::Helpintfs::IHelpSystem' is an abstract class
unknwn.h(114): unimplemented pure virtual method 'QueryInterface' in 'IHelpSystem'
unknwn.h(118): unimplemented pure virtual method 'AddRef' in 'IHelpSystem'
unknwn.h(120): unimplemented pure virtual method 'Release' in 'IHelpSystem'
System.HelpIntfs.hpp(66): unimplemented pure virtual method 'ShowHelp' in 'IHelpSystem'
System.HelpIntfs.hpp(67): unimplemented pure virtual method 'ShowContextHelp' in 'IHelpSystem'
System.HelpIntfs.hpp(68): unimplemented pure virtual method 'ShowTableOfContents' in 'IHelpSystem'
System.HelpIntfs.hpp(69): unimplemented pure virtual method 'ShowTopicHelp' in 'IHelpSystem'
System.HelpIntfs.hpp(70): unimplemented pure virtual method 'AssignHelpSelector' in 'IHelpSystem'
System.HelpIntfs.hpp(71): unimplemented pure virtual method 'Hook' in 'IHelpSystem'
Here are the help pages from the Embaradero website that discuss IHelpSystem.
IHelpSystem
HelpIntfs.GetHelpSystem
As the error message says, IHelpSystem is an abstract class (it has pure virtual methods that are implemented in derived classes), and as such you can't instantiate it directly, like you are trying to do in your C++ code:
IHelpSystem HelpSystem;
You can declare variables of this type only by pointer (IHelpSystem*) or reference (IHelpSystem&). And indeed, the C++ equivalent of the Delphi statement:
var HelpSystem: IHelpSystem;
is:
IHelpSystem* HelpSystem;
But, since IHelpSystem is a Delphi-based interface, you actually need to use the _di_IHelpSystem wrapper type (which is an alias for DelphiInterface<IHelpSystem>), which is what GetHelpSystem() actually outputs in C++:
extern DELPHI_PACKAGE bool __fastcall GetHelpSystem(/* out */ _di_IHelpSystem &System)/* overload */;
Try this instead:
#include <System.HelpIntfs.hpp>
void __fastcall TForm99::btnShowTopicClick(TObject *Sender)
{
_di_IHelpSystem HelpSystem;
GetHelpSystem(HelpSystem);
if (HelpSystem)
HelpSystem->ShowTopicHelp(_D("topic3"), Application->HelpFile);
}

type TMessage is not a defined class with virtual function C++ builder sample

Im trying to use embarcadero sample on useing android camera and geting an error:
"type TMessage is not a defined class with virtual function" on lines:
void __fastcall TForm1::DoMessageListener(const TObject *Sender, TMessage const *M) {
TMessageDidFinishTakingImageFromLibrary const *v = dynamic_cast<TMessageDidFinishTakingImageFromLibrary const *>(M);
if (v) {
Image1->Bitmap->Assign(v->Value);
}
}
In Delphi, TMessage works fine, but in C++Builder you must use TMessageBase instead:
void __fastcall TForm1::DoMessageListener(const TObject *Sender, TMessageBase const *M)
This is clearly stated in the documentation:
Sending and Receiving Messages Using the RTL:
The RTL only defines one type of message, TMessage. It is actually a template that you can use to create messages for specific types of values; for example: TMessage<int> or TMessage<UnicodeString>. You can also subclass TMessage to define your own message types or, if you are using FireMonkey, you can reuse the message types defined by the framework.
Note: For C++ projects use TMessageBase instead of TMessage.
System.Messaging.TMessage
TMessage represents the base class used for message purposes. It can be inherited in order to send custom messages.
Warning: For C++ projects, use TMessageBase instead.
System.Messaging.TMessageBase
Alias to System.Messaging.TMessage.
Use System.Messaging.TMessageBase for C++ projects instead of System.Messaging.TMessage.
This use of TMessageBase is also demonstrated in the documentation's System.Messaging (C++) example.

C++ Builder E2303 Type name expected

I am attempting to use the HP APDK with C++ Builder in RAD Studio XE5. I need to derive a class PlatformServices (or any name of my choosing) from HP's base class SystemServices. Here is my header PlatformServices.h:
/***************************************************************************\
APDK Platform Services
\***************************************************************************/
#ifndef _H_PLATFORMSERVICES
#define _H_PLATFORMSERVICES
#include "header.h" // HP APDK General Header
// class SystemServices {
// };
class PlatformServices : public SystemServices {
~PlatformServices ();
PlatformServices ();
};
#endif
Compiled as-is, I get the error:
[bcc32 Error] PlatformServices.h(13): E2303 Type name expected
Full parser context
PlatformServices.cpp(5): #include PlatformServices.h
PlatformServices.h(13): class PlatformServices
But if I comment out the #include and uncomment the definition for an empty class named SystemServices, the code compiles without error.
I can preprocess the code as-is (in Project Manager, right click on PlatformServices and select Preprocess) and I can see that the #include defines a well formed SystemServices class.
I've also disabled pre-compiled headers.
This seems like a compiler error, but it's a poor workman who blames his tools. I just can't believe C++ Builder would choke on something this basic, yet I can't see what I'm doing wrong. Help!
P.S. I've posted the full code and project files at: https://www.dropbox.com/s/sn1377y59r3idtz/apdk.zip
SystemServices is declared in the apdk namespace, so you need to specify that in your code, either directly:
class PlatformServices : public apdk::SystemServices
Or with a using namespace statement:
using namespace apdk;
class PlatformServices : public SystemServices

How do I construct this Delphi class in C++Builder?

What is the C++ equivalent of this code
ImageEnView1.IEBitmap.VirtualBitmapProvider := TIESlippyMap.Create();
I get a compile error
[bcc32 Error] Unit1.cpp(12907): E2285 Could not find a match for 'TIESlippyMap::TIESlippyMap()'
on my code
ImageEnview1->IEBitmap->VirtualBitmapProvider = new TIESlippyMap();
ImageEnView1->IEBitmap->VirtualBitmapProvider = new TIESlippyMap();
Update: You are trying to call this constructor:
constructor Create(provider:TIESlippyMapProvider = iesmpMapQuest; const cachePath:string = '');
The compiler error you are getting means that the C++ compiler cannot find a constructor that has no parameters, or at least a constructor with parameters that all have default values assigned to them. Depending on which C++Builder version you are using, it is likely that the Delphi compiler included with it is not emitting the default parameter values when generating the C++ .hpp file for the class. Older Delphi compiler versions did not do that correctly, but newer versions do. In which case, it sounds like you are using an affected version, so you will have to fill in those parameter values explicitly:
ImageEnView1->IEBitmap->VirtualBitmapProvider = new TIESlippyMap(iesmpMapQuest, "");
Or else edit the .hpp file to include the default values correctly:
class TIESlippyMap : public ...
{
...
public:
__fastcall TIESlippyMap(TIESlippyMapProvider provider = iesmpMapQuest, const String cachePath = "");
...
};

Resources