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

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);
}

Related

Unresolved external linker error in 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.

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.

How to inherit a record from other record in Delphi (like in C++)?

I want solutions for RAD Studio 10.2 Berlin, same like in C++.
Inherit a record from another record (see following C++ example):
typedef struct A
{
virtual int ChangeName(const char* Name) = 0;
} A;
struct B : public A
{
virtual int ChangeValue(const char* Value) = 0;
};
How are pure virtual functions implemented in Delphi?
Record inheritance is not supported in the Delphi language.
The closest equivalent to a C++ pure virtual function in Delphi is an abstract virtual method. But there are no virtual methods in Delphi records because record inheritance is not supported in the Delphi language.
You can learn all this and more from the documentation. Some key excerpts:
Records do not support inheritance.
...
Virtual methods (those specified with the virtual, dynamic, and message keywords) cannot be used in record types.

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.

Missing assembly reference when using class

I have the following code
class clazz
{
constructor {:axiom} () requires true
method su(x: int, y:int) returns (r: int)
{
r := x + y;
}
}
method {:main} Main() {
var c := new clazz();
var s := c.su(2,3);
print(s);
}
How can one make use of the clazz class? This is the specific error:
error CS1061: Type `__default.ClassRoomExample' does not contain a definition for `__ctor'and no extension method `__ctor' of type `__default.ClassRoomExample' could be found. Are you missing an assembly reference?
I've just figured out the problem. missing a { } in the constructor. Dumb.
Normally, the Dafny compiler would complain that you have declared something without a body, in this case a constructor without a body. But you have marked your constructor with {:axiom}, which tells the compiler that you left out of the body intentionally. That's why the error you're seeing comes from the C# compiler, not the Dafny compiler.
The {:axiom} attribute, which is uncommon, was designed for body-less lemmas. If you really want to omit the code for a constructor or method, you probably want to use the :extern attribute instead, which lets you implement the method in another .NET language.

Resources