How can I translate this code into C++? UniGui component.
var
FrmList : TList;
I : Integer;
Frm : TUniBaseForm;
begin
FrmList := UniSession.FormsList;
UniListBox1.Clear;
for I := 0 to FrmList.Count - 1 do
begin
Frm := FrmList[I];
UniListBox1.Items.Add(Frm.Name + ' ' + Frm.ClassName );
end;
I have a problem with Frm := FrmList[i];. I have tried:
frm = UniSession->FormsList->Items[i];
E2034 Cannot convert 'void *' to 'TUniBaseForm *'
frm = dynamic_cast<TUniBaseForm*>(UniSession->FormsList->Items[i]);
E2307 Type 'void' is not a defined class with virtual functions
frm = dynamic_cast<TUniBaseForm*>(UniSession->FormsList[i]);
E2031 Cannot cast from 'TList' to 'TUniBaseForm *'
Delphi allows an untyped pointer (void* in C++) to be assigned to another typed pointer without a cast. C++ does not, you need an explicit cast.
You were on the right track with your 2nd attempt, but you need to use either static_cast or reinterpret_cast, instead of dynamic_cast, eg:
TUniBaseForm *Frm = static_cast<TUniBaseForm*>(FrmList->Items[i]);
or
TUniBaseForm *Frm = reinterpret_cast<TUniBaseForm*>(FrmList->Items[i]);
See these related questions:
Should I use static_cast or reinterpret_cast when casting a void* to whatever
When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
Related
Ok I'm trying to write this under the WFSExecute but if I type:
WFSPINGETDATA * pingetdata = lpCmdData;
I get an error:
errorC2440: 'initializing' : cannot convert from 'LPVOID' to 'WFSPINGETDATA *'
If I comment out that line, the app execute.
Also, if I write:
((WFSPINDATA*) (temp)) ->lpPinKeys = malloc(sizeof(LPWFSPINKEY)*NumberOfKeys) ;
I get an error:
errorC2440: '=' cannot convert from 'void' to 'LPWFSPINKEY *'
Any solution to solve this?
C++ is more strict on type safety than C is. In this case, void* must be type-casted when assigned to anything other than another void*.
WFSPINGETDATA * pingetdata = lpCmdData;
cannot convert from 'LPVOID' to 'WFSPINGETDATA *'
This means lpCmdData is a void*, so a type-cast is needed:
WFSPINGETDATA * pingetdata = (WFSPINGETDATA*) lpCmdData;
Or, using a C++-style cast instead of a C-style cast:
WFSPINGETDATA * pingetdata = static_cast<WFSPINGETDATA*>(lpCmdData);
((WFSPINDATA*) (temp)) ->lpPinKeys = malloc(sizeof(LPWFSPINKEY)*NumberOfKeys) ;
cannot convert from 'void' to 'LPWFSPINKEY *'
malloc() returns a void*, so a type-cast is needed here as well:
((WFSPINDATA*) (temp)) ->lpPinKeys = (LPWFSPINKEY*) malloc(sizeof(LPWFSPINKEY)*NumberOfKeys);
Or, using C++-style casts:
static_cast<WFSPINDATA*>(temp)->lpPinKeys = static_cast<LPWFSPINKEY*>(malloc(sizeof(LPWFSPINKEY)*NumberOfKeys));
Or, using C++-style allocation instead of C-style allocation:
static_cast<WFSPINDATA*>(temp)->lpPinKeys = new LPWFSPINKEY[NumberOfKeys];
// must use 'delete[] lpPinKeys' instead of 'free(lpPinKeys)' to deallocate the memory
I am writing a Win32 application with Awesomium. According to the tutorial section I can load a local file inside my view:
WebURL url(WSLit("file:///C:/dev/project/util/ui/index.html"));
view_->web_view()->LoadURL(url);
This works as expected.
When I try to pass an std::wstring to WSList function:
std::wstring ui_path = L"file:///" + install_path + L"/util/ui/index.html";
WebURL url(WSLit(ui_path));
view_->web_view()->LoadURL(url);
I get a compiler error:
src/main.cc(52) : error C2664: 'Awesomium::WSLit' : cannot convert parameter 1 from
'std::wstring' to 'const char *' No user-defined-conversion operator available that can
perform this conversion, or the operator cannot be called
When I try to pass WSLit( ui_path.c_str() ) the compiler throws another error:
src/main.cc(52) : error C2664: 'Awesomium::WSLit' : cannot convert parameter 1 from
'const wchar_t *' to 'const char *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or
function-style cast
What is the right way to convert it to const char * type?
Edit:
From Awesomium documentation :
WSLit() is a special helper function that lets you declare WebString literals. Most of our API uses UTF-16 strings (wrapped with WebString) but we added WSLit() so you can declare ASCII C-strings with minimal fuss.
WSLit is meant to construct a WebString object from an ASCII string. Since you don't want to construct a WebString from ASCII, but rather have a UNICODE string from the beginning, you simply don't need to use WSLit at all.
The following line of code constructs a WebURL from a std::wstring:
WebURL url(WebString(ui_path.c_str()));
As pointed out by Remy Lebeau this may not compile for any given compiler or compiler settings. WebString has an explicit constructor taking a const wchar16*. Platform.h defines wchar16 as
typedef unsigned short wchar16;
Depending on your compiler and compiler settings, this may or may not be the same as wchar_t. When compiling with the Microsoft compiler using the command line option /Zc:wchar_t, wchar_t is interpreted as a native data type. This is a different type from unsigned short, and the explicit constructor of WebString requires an additional cast:
WebURL url(WebString(reinterpret_cast<const wchar16*>(ui_path.c_str())));
Implicitly invoking the conversion constructor of WebString using the following syntax is not possible, since it is declared explicit:
WebURL url(reinterpret_cast<const wchar16*>(ui_path.c_str()));
If the question is "convert std::wstring to const char*", I usually use this function and it works fine:
std::string wstringToString(const std::wstring& in){
std::string result(in.begin(), in.end());
return result;
}
And then, you can get char* by calling result.c_str();
Try this one:
std::wstring ui_path = L"file:///" + install_path + L"/util/ui/index.html";
std::string cui_path( ui_path.begin(), ui_path.end() );
WebURL url(WSLit(cui_path));
view_->web_view()->LoadURL(url);
However, IMHO, if Awesomium is intended to run under Windows, the WSLit constructor should support either a std::wstring or wchar_t * argument.
I have defined a struct that stores the length and content of a string.
struct sir {
int length;
char* string;
};
I am trying to dynamically alocate memory space for this string using:
s->string = malloc(sizeof(char) * (s->length));
But I keep getting this error:
error C2440: '=' : cannot convert from 'void *' to 'char *'
Can you please guide in finishing this function?
PS: I would really like to know how write values from keyboard in this newly created string?
Tnx in advance!
malloc() will return void *, which needs to be converted to char * explicitly in C++ (though not needed in C).
Try
s->string = (char *) malloc(sizeof(char) * (s->length));
Edit: As you're using C++, as #chris commented, you should consider to use std::string instead. No manual memory management is needed. If you must do it yourself, use new instead of malloc.
You are compiling the program as a C++ program. The return type of function malloc is void * However a pointer to void may not be implicitly converted to a pointer to other type in C++ and the error message says about this clear enough.
So write
s->string = ( char * )malloc(sizeof(char) * (s->length));.
However the coorect way is to use operator new instead of malloc in C++
s->string = new char[s->length];.
Again if it is a C++ program then instead of the structure it would be better to use a class with explicitly defined constructors, destructor and the copy bassignment operator.
Or compile your program as a C program if you indeed want to deal with a C program.
This gives the error: cannot convert from 'const char *' to 'char *'.
class Mock
{
public:
...
static void func(char **result)
{
*result = (resultsI++)->c_str();
}
static std::vector<std::string> results;
static std::vector<std::string>::iterator resultsI;
};
std::vector<std::string> Mock::results;
std::vector<std::string>::iterator Mock::resultsI;
How can I validly get rid of this error without changing the interface to the function func? The implementer of this interface:
void (func*)(char **result)
forgot to use const char** in the signature. I can't change it.
Remember this is a mock and I'm only used in my unit tests.
Try:
*result = &(*resultsI++)[0];
Although this isn't guaranteed to work prior to C++11 it is known to be OK on most or all current compilers.
The danger is that if the function tries to change the length of the string, you could get some nasty errors. Changing individual characters should be OK.
In test code, and if you are certain that the user of the interface isn't going to mutate the char*, maybe you could use a const_cast?
That assumes the caller doesn't take ownership of the char *; if that is the case, then you should make a copy.
If you're absolutely certain that the interface function will not modify the string, you can use
*result = const_cast<char *>((resultsI++)->c_str());
to remove constness.
Otherwise, another option is to switch from using std::vector<std::string> to std::vector<std::vector<char>> but then you'll have to make sure you properly null terminate the strings.
Windows 7 64 SP1 --
MongoDB 2.2.0-rc2 --
Boost 1.42 --
MS VS 2010 Ultimate --
C++ driver
I've written this function:
void printQuery(DBClientConnection &c, std::string &dc, const Query &qu = BSONObj(), std::string sortby = "" )
This fragment:
auto_ptr<DBClientCursor> cursor;
cursor = c.query(dc,qu.sort(sortby))
raises the error:
error C2663: 'mongo::Query::sort' : 2 overloads have no legal conversion for 'this' pointer.
sort (const string &field, int asc=1) should be the applicable overload. I believe this is something to do with using const Query& with its member function sort. But if I change it to Query& without the const, then my parameter initialization = BSONObj() raises:
cannot convert from 'mongo::BSONObj' to 'mongo::Query &'
If I pass by value, then it compiles fine.
Is there a way to avoid either of the errors (beside passing by value)?
Thanks!
David Hows at MongoDB-user walked me through the solution:
Instead of const Query &qu = BSONObj(), use Query &qu = Query().
I was getting an error using const "because sort will change the value of the query object - which is defined as a constant." So I dropped it.
Using BSONObj() as the default is problematic because I'm not "creating a new object but assigning a new BSONObj into a variable for a Query object, nothing new is being created thus no constructor call."
So I used Query() instead. if ( qu.obj == BSONObj() ) works for testing if qu is empty.
My final function is:
void printQuery(DBClientConnection &c, const string &dc, Query &qu = Query(), const string &sortby = "" )
I couldn't make the DBClientConnection qualified as const. It raised the no legal conversion for 'this' pointer when using c.query and
C2662: 'mongo::DBClientWithCommands::count' : cannot convert 'this' pointer from 'const mongo::DBClientConnection' to 'mongo::DBClientWithCommands &' Conversion loses qualifiers
when using c.count. So I kept it unqualified.
You should be sorting the cursor and not on qu, which I presume to be your BSON query. eg.
auto_ptr<DBClientCursor> cursor;
cursor = c.query(dc,qu).sort(sortby)
Check out http://www.mongodb.org/pages/viewpage.action?pageId=133415#C%2B%2BTutorial-Sorting for more information.