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 = "");
...
};
Related
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.
I am using the code below in C++Builder XE4 VCL 32bit. I am using the Indy components, version 10.6.0.497.
I have been using IdHTTP->Get() with HTTP addresses that have now changed to HTTPS. I believe I need to create a TIdSSLIOHandlerSocketOpenSSL component and add it to TIdHTTP as its IOHandler.
When I try to do this, the code below gives the error:
E2451 Undefined symbol 'TIdSSLIOHandlerSocketOpenSSL'
The error is on the code, std::auto_ptr<TIdSSLIOHandlerSocketOpenSSL>.
I am not sure why TIdSSLIOHandlerSocketOpenSSL is undefined, because I have Indy installed and can use TIdSSLIOHandlerSocketOpenSSL as a traditional component from the component palette.
Can anyone show me how I can set this code up to use HTTPS addresses?
std::auto_ptr<TIdSSLIOHandlerSocketOpenSSL> Local_IOHandler( new TIdSSLIOHandlerSocketOpenSSL( NULL ) );
//error: E2451 Undefined symbol 'TIdSSLIOHandlerSocketOpenSSL'
//error: E2299 Cannot generate template specialization from 'std::auto_ptr<_Ty>'
std::auto_ptr<TIdHTTP> Local_IdHTTP( new TIdHTTP( NULL ) );
Local_IdHTTP->Name="MyLocalHTTP";
Local_IdHTTP->HandleRedirects=true;
Local_IdHTTP->IOHandler=Local_IOHandler;
TStringStream *jsonToSend = new TStringStream;
UnicodeString GetURL = "https://chartapi.finance.yahoo.com/instrument/1.0/CLZ17.NYM/chartdata;type=quote;range=1d/csv/";
jsonToSend->Clear();
try
{
Local_IdHTTP->Get(GetURL, jsonToSend);
}
catch (const Exception &E)
{
ShowMessage( E.Message );
//error: IOHandler value is not valid
}
When I try to do this the code below gives the error E2451 Undefined symbol 'TIdSSLIOHandlerSocketOpenSSL'
Add #include <IdSSLOpenSSL.hpp> to your code.
I am not sure why 'TIdSSLIOHandlerSocketOpenSSL' is Undefined because I have Indy installed and can use 'TIdSSLIOHandlerSocketOpenSSL' as a traditional component from the compoenent pallet?
Dropping a component onto your Form at design-time auto-generates any necessary #include statements for you. TIdSSLIOHandlerSocketOpenSSL is no different.
That being said, once you get that fixed, you cannot assign a std::auto_ptr itself to the IOHandler. You need to use its get() method to get the object pointer:
Local_IdHTTP->IOHandler = Local_IOHandler.get();
And you should consider using std::auto_ptr for your TStringStream as well:
std::auto_ptr<TStringStream> json( new TStringStream );
Local_IdHTTP->Get(GetURL, json.get());
// use json as needed...
Though in this situation, I would suggest using the overloaded version of TIdHTTP::Get() that returns a String instead, there is no benefit to using a TStringStream:
String json = Local_IdHTTP->Get(GetURL);
// use json as needed...
I have the following C# method:
private static bool IsLink(string shortcutFilename)
{
var pathOnly = Path.GetDirectoryName(shortcutFilename);
var filenameOnly = Path.GetFileName(shortcutFilename);
var shell = new Shell32.Shell();
var folder = shell.NameSpace(pathOnly);
var folderItem = folder.ParseName(filenameOnly);
return folderItem != null && folderItem.IsLink;
}
I have tried converting this to F# as:
let private isLink filename =
let pathOnly = Path.GetDirectoryName(filename)
let filenameOnly = Path.GetFileName(filename)
let shell = new Shell32.Shell()
let folder = shell.NameSpace(pathOnly)
let folderItem = folder.ParseName(filenameOnly)
folderItem <> null && folderItem.IsLink
It however reports an error for the let shell = new Shell32.Shell() line, saying that new cannot be used on interface types.
Have I just made a silly syntactic mistake, or is there extra work needed to access COM from F#?
I don't know enough about the F# compiler but your comments makes it obvious enough. The C# and VB.NET compilers have a fair amount of explicit support for COM built-in. Note that your statement uses the new operator on an interface type, Shell32.Shell in the interop library looks like this:
[ComImport]
[Guid("286E6F1B-7113-4355-9562-96B7E9D64C54")]
[CoClass(typeof(ShellClass))]
public interface Shell : IShellDispatch6 {}
IShellDispatch6 is the real interface type, you can also see the IShellDispatch through IShellDispatch5 interfaces. That's versioning across the past 20 years at work, COM interface definitions are immutable since changing them almost always causes an undiagnosable hard crash at runtime.
The [CoClass] attribute is the important one for this story, that's what the C# compiler goes looking for you use new on a [ComImport] interface type. Tells it to create the object by creating an instance of Shell32.ShellClass instance and obtain the Shell interface. What the F# compiler doesn't do.
ShellClass is a fake class, it is auto-generated by the type library importer. COM never exposes concrete classes, it uses a hyper-pure interface-based programming paradigm. Objects are always created by an object factory, CoCreateInstance() is the workhorse for that. Itself a convenience function, the real work is done by the universal IClassFactory interface, hyper-pure style. Every COM coclass implements its CreateInstance() method.
The type library importer makes ShellClass look like this:
[ComImport]
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
[ClassInterface(ClassInterfaceType.None)]
[Guid("13709620-C279-11CE-A49E-444553540000")]
public class ShellClass : IShellDispatch6, Shell {
// Methods
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0x60040000)]
public virtual extern void AddToRecent([In, MarshalAs(UnmanagedType.Struct)] object varFile, [In, Optional, MarshalAs(UnmanagedType.BStr)] string bstrCategory);
// Etc, many more methods...
}
Lots of fire and movement, none of it should ever be used. The only thing that really matters is the [Guid] attribute, that provides the CLSID that CoCreateInstance() needs. It also needs the IID, the [Guid] of the interface, provided by the interface declaration.
So the workaround in F# is to create the Shell32.ShellClass object, just like the C# compiler does implicitly. While technically you can keep the reference in a ShellClass variable, you should strongly favor the interface type instead. The COM way, the pure way, it avoids this kind of problem. Ultimately it is the CLR that gets the job done, it recognizes the [ClassInterface] attribute on the ShellClass class declaration in its new operator implementation. The more explicit way in .NET is to use Type.GetTypeFromCLSID() and Activator.CreateInstance(), handy when you only have the Guid of the coclass.
I have a snippet of code which compiles in C++ Builder XE8 using the classic BCC compiler. However, in Rad Studio 10 Seattle using the Clang compiler I get the error
'no matching constructor found for initialization of TChoiceItem'
Here is the snippet of code which causes the error.
LISTITEM_BEGIN( sch_TYPE_Choice )
LISTITEM_DATA( sch_TYPE_Daily, "Daily" )
LISTITEM_DATA( sch_TYPE_Weekly, "Weekly" )
LISTITEM_DATA( sch_TYPE_Monthly, "Monthly" )
LISTITEM_END()
Here is the code which defines TChoiceItem
//------------------------------------------------------------------------------
#define LISTITEM_BEGIN( Name ) TChoiceItem Name[] = {
//------------------------------------------------------------------------------
#define INT_LISTITEM_BEGIN( Name ) TIntChoiceItem Name[] = {
//------------------------------------------------------------------------------
#define LISTITEM_DATA( XCode, XText ) { XCode, 0, (char*)XText, 0 },
#define LISTITEM_DATA_NC( XShortText, XText ) { 0, (char*)XShortText, (char*)XText, 0 },
#define LISTITEM_DATA_EX( XCode, XShortText, XText ) { XCode, (char*)XShortText, (char*)XText, 0 },
#define LISTITEM_DATA_EX2( XCode, XShortText, XText, XDesc ) { XCode, (char*)XShortText, (char*)XText, (char*)XDesc },
#define LISTITEM_END() LISTITEM_DATA(0,0) };
I am fairly new to C++ so I am not exactly sure what to call the above method of defining a class/method.
Is this some sort of dated language feature not supported by the Clang compiler? Is there a way to modify the code or definition so the compiler will accept it?
Edit:
I found the actual declaration of the TChoiceItem class.
class TChoiceItem : public TChoiceBase
{
public:
char Code;
char *ShortText;
char *Text;
char *Desc;
};
It does't appear to have any sort of standard constructor at all. But somehow, everything still compiles and works with the classic BCC compiler.
Edit 2:
I found this question which looks to be describing a similar issue. Could it be that I need to include some kind of compiler flag when compiling the code? If so can I add a flag somehow in the embarcadero project compiler settings?
Using a list of values in braces to initialize the individual members of a class or struct is known as aggregate initialization.
As explained on cppreference.com, aggregate initialization isn't permitted if the class has a base class (among other restrictions). TChoiceItem inherits from TChoiceBase, so aggregate initialization isn't allowed (and the "classic" bcc32 compiler shouldn't have allowed it).
You have a couple of choices:
First, you can change the code to not inherit from TChoiceBase.
Second, you can define a constructor:
TChoiceItem(char code, char *short_text, char *text, char *desc)
: Code(code), ShortText(short_text), Text(text), Desc(desc) {}
C++11's uniform initialization means that your macros' syntax doesn't have to change: instead of braces meaning a list of values for individual members, the braces will mean a list of parameters to the constructor, but the result will be the same.
I want to create a symbol equal to that of a private MethodMirror's simplename. However, Symbol's documentation states the argument of new Symbol must be a valid public identifier. If I try and create a const Symbol('_privateIdentifier') dart editor informs me that evaluation of this constant expression will throw an exception - though the program runs fine, and I am able to use it without any issues.
void main(){
//error flagged in dart editor, though runs fine.
const s = const Symbol('_s');
print(s); //Symbol("_s");
}
It seems the mirror system uses symbols.
import 'dart:mirrors';
class ClassA{
_privateMethod(){}
}
void main(){
var classMirror = reflect(new ClassA()).type;
classMirror.declarations.keys.forEach(print);
//Symbol("_privateMethod"), Symbol("ClassA")
}
Is the documentation/error flagging in dart editor a legacy bug due to an outdated dart analyzer? Or are there plans to enforce this public requirement in future? Is there another way to create a unique identifying symbol that will be minified to the same symbol as the declaration's simple name
If it doesn't throw then the VM has a bug in the const Symbol constructor.
The problem is that "_s" does not identify a private variable without also saying which library it belongs to. The symbol constructor has a second argument taking a LibraryMirror for that reason, and passing in a private name without also passing in a mirror should throw.
That's hard to do in a const constructor without side-stepping the requirements of a const constructor (no executing code!), which is likely why the VM doesn't handle it. It needs to be special-cased at the compiler level.
You will also find that const Symbol('_s') is not the same as #_s. The latter creates a private symbol for the current library, the former (if it runs) creates a non-private symbol with the name '_s', which is not really useful. For example print(identical(#_s, const Symbol('_s'))); prints false.
The To get hold of the symbol I think you would need to get it from the object. e.g.
reflect(thing).type.declarations.keys.firstWhere(
(x) => MirrorSystem.getName(x) == "_privateThingIWant");