I need to pass one of my parameters to a write() function. It is asking for a type of 'const void*' I am a PHP guy and don't know C++ very well.
Here is my parameter:
const fmx::Text& distance = dataVect.AtAsText(3);
I don't know of any other way to pull in that field. I would love to just declare it const void* but I don't know how.
I guess just converting it would be easier than trying to pull it in the correct way??
The error message: cannot convert const fmx::Text to const void* for argument 2
write(fd, distance, 4);
I know this worked so can I just convert?
const void* s = "5000";
This is for a plugin in FileMaker so I don't really get c++ here.
Is there more anyone would need to help me solve this??
Thanks so much!
If fmx::Text was a pointer type, the compiler would automatically convert a reference to it into a void*. You need to use the address-of operator to give the function a pointer to work with:
write(fd, &distance, 4);
I don't really know filemaker, but this link shows that fmx::Text has a GetBytes function. You can then pass the pointer to the buffer filled with this function.
I'm assuming you actually want the text string.
I think you need to check the api for fmx::Text to get the string you want. Here is something I found to get the string out.
Looks like the type stores the data as UTF16, so you have to run a bit of code to get a string out, then pass it to your write function:
//a function to convert to a normal string
std::string getString(fmx::Text& Text)
{
char buffer[512] = {0}; //NOTE YOU HAVE A STRING SIZE LIMIT
// convert original text to ASCII text
outText.GetBytes( buffer, sizeof(buffer)-1, 0, Text.GetSize(), fmx::Text::kEncoding_Native );
return buffer;
}
Then call the function
std::string myString = getString(distance);
write(fd, myString.c_str(), myString.size());
Note I'm assuming a lot here...that you want a string in the current encoding, and not the raw UTF16 data from 'distance'. AND that GetBytes will not mangle the null characters in buffer....
You'll also need to include <string> in your c++ file.
Related
I am now using C++ to program a robot using PROS. Pros has a print function, which is taking in a const char*. Now, I'm using lvgl to create my own screen, and I want to replicate the print function. Like the printf() functions, I want it to include variadic params to do the %d effect (so it converts all the %? to the corresponding values). The problem now is about the conversions between functions. I wanted to make a convert function to convert a string and the variadic params into a complete string. I need to input is a string which is like "hey" and I'm unsure what the type name should be. I need to be able to get size, search in it for %ds but I need the function to return a const char* to pass onto the lvgl to pring on the screen. I am having a bad time trying to convert a string into an const char* for the out put of the convert function.
Also, I tried using the input type as a char*, and when I input a string like "hello" is says a error [ISO C++11 does not allow conversion from string literal to 'char ' [-Wwritable-strings]]. But instead, when is use a const char, the error disappears. Anyone knows why?
Thanks everyone for your kind help!
char* and const char* are two flavours of the same thing: C-style strings. These are a series of bytes with a NUL terminator (0-byte). To use these you need to use the C library functions like strdup, strlen and so on. These must be used very carefully as missing out on the terminator, which is all too easy to do by accident, can result in huge problems in the form of buffer-overflow bugs.
std::string is how strings are represented in C++. They're a lot more capable, they can support "wide" characters, or variable length character sets like UTF-8. As there's no NUL terminator in these, they can't be overflowed and are really quite safe to use. Memory allocation is handled by the Standard Library without you having to pay much attention to it.
You can convert back and forth as necessary, but it's usually best to stick to std::string inside of C++ as much as you can.
To convert from C++ to C:
std::string cppstring("test");
const char* c_string = cppstring.c_str();
To convert from C to C++:
const char* c_string = "test";
std::string cppstring(c_string);
Note you can convert from char* (mutable) to const char* (immutable) but not in reverse. Sometimes things are flagged const because you're not allowed to change them, or that changing them would cause huge problems.
You don't really have to "convert" though, you just use char* as you would const char*.
std::string A = "hello"; //< assignment from char* to string
const char* const B = A.c_str(); //< call c_str() method to access the C string
std::string C = B; //< assignment works just fine (with allocation though!)
printf("%s", C.c_str()); //< pass to printf via %s & c_str() method
I'm learning D language (I know C++ well)... I want to do some Windows specific stuff so I wrote this just to try out the API:
import core.sys.windows.windows;
import std.stdio;
string name()
{
char buffer[100];
uint size = 100;
GetComputerNameA(&buffer[0], &size);
return buffer;
}
void main()
{
writeln(name());
}
I get in my return statement:
test.d(11): Error: cannot implicitly convert expression (buffer) of type char[100] to string
Ok, in C++ it would call the constructor to make a string. It says implicit so lets cast it with a C style cast: return (string)buffer;.
test.d(11): Error: C style cast illegal, use cast(string)buffer
Ah ok, I remember, different syntax.
return cast(string)buffer;
Now it compiles but I just get garbage.
I assume that is is because it's storing a pointer in the string to the temporary buffer. I don't want to do this, I want to copy the characters into a string but annoyingly I can't seem to find how to do this?
So questions:
How do I construct an actual string from a char array that allocates storage properly? (Copies the characters)
Allocating a buffer of a random size like this and converting to a string seems ugly. Is there a proper way to do this in D? (I'm talking about the general question, not specifically this API just in case there is another API to get the computer name).
If either of those are answered in a manual where should I have looked to find details?
Thanks for any help and advice.
I think you need:
string name()
{
char buffer[100];
uint size = 100;
GetComputerNameA(buffer.ptr, &size);
return buffer[0 .. size].idup;
}
buffer.idup is the standard way to get an immutable copy. For this case, since you want a dynamically-sized string (and recall that string is really just shorthand for immutable(char)[]), you want buffer[0..size].idup, using D's array slicing.
See http://dlang.org/arrays.html for more information.
(This is a bit of a nitpick, but you may want to use buffer.ptr instead of &buffer[0], mostly for readability's sake.)
I'm having issues with a type conversion that I can't explain.
Here is what i would like to do
I have a buffer that I dynamically allocate and i need to convert it to a string in order to use a parsing function from an external library.
My implementation
unsigned char* msg_data;
msg_data = (unsigned char*)malloc(msg_data_length);
string msg_data_str = std::string(reinterpret_cast<const char*>(_msg_data));
SomeObject myObject;
myObject.ParseFromString(msg_data_str);
But here is the thing : my parsing function fails because it receives the wrong size of data.
Let's say that i have a buffer of size msg_data_length = 10, the size of my string is my_data_str.size() = 14.
I get rid of my problem by using my_data_str.resize(my_data_length)
but I would like to understand why the size of my_data_str is not directly msg_data_length.
Thanks for your help !
I assume that the message data is not actually zero-terminated like a C-style string, which leads to undefined behavior when the std::string constructor is going out of bounds to find the terminator.
To fix this, use the constructor taking two arguments, the string and the length.
See e.g. this std::string constructor reference.
I am trying to convert a const char pointer to a constant wide string pointer. Here is my code.
double ret;
const wchar_t* file;
file = const wchar_t* (file_old);
I get something that says this: "Error, type name not allowed." over the const.
Any help is greatly appreciated!
You need to actually convert the contents to which the pointer points to wide characters. The easiest way to do that is probably to put the narrow version into a string and convert using wstring_convert as detailed in this answer: https://stackoverflow.com/a/18374698/82320
I've got a function that returns a std::string object. I'm working with Cocoa/CoreGraphics and I need a way to get the data from that string into a CFData object so that I can feed that into a CGDataProviderCreateWithCFData object to make a CGImage.
The CreateCFData function wants a const UInt8* object (UInt8 being a typedef for unsigned char). The string represents the bytes from a decoded Base64 string (image data), so it appears to contain many null "characters" so the obvious casting of the .c_str() output to an unsigned char* object won't work.
I'm less experienced with C++ and very new to Cocoa/CoreGraphics, so if there's a much better way to accomplish what I'm wanting to do please let me know.
CFDataCreate( NULL, (const UInt8*) myString.data(), myString.size() )