LLVM IR String Initialization - string

I'm working on a program in LLVM IR, and I am trying to initialize a string that says "Hello World!" but I can't figure out how. The goal of the code is to count the number of characters in the string. Before the string needs to be initialized, and after the headers, I have the following:
int main (int argc, const char *argv[]) {
//Setting up
//Build a pointer to the string - LLVMValueRef *strptr=LLVMBuildGlobalStringPtr(builder, const char *string, const char *name);
LLVMValueRef *strptr;
LLVMContextRef context = LLVMContextCreate();
LLVMBuilderRef builder = LLVMCreateBuilderInContext (context);
LLVMModuleRef module1 = LLVMModuleCreateWithNameInContext("mod", context);
}

The easiest way to see how such things are by using the C++ backend - it generates the C++ API calls that build the module for you. You can see this done online.
"Compile" this code:
const char* foo() {
const char* s = "hello world";
return s;
}
And here are the relevant C++ API calls:
GlobalVariable* gvar_array__str = new GlobalVariable(/*Module=*/*mod,
/*Type=*/ArrayTy_0,
/*isConstant=*/true,
/*Linkage=*/GlobalValue::PrivateLinkage,
/*Initializer=*/0, // has initializer, specified below
/*Name=*/".str");
gvar_array__str->setAlignment(1);
// Constant Definitions
Constant *const_array_4 = ConstantDataArray::getString(mod->getContext(), "hello world", true);
std::vector<Constant*> const_ptr_5_indices;
ConstantInt* const_int64_6 = ConstantInt::get(mod->getContext(), APInt(64, StringRef("0"), 10));
const_ptr_5_indices.push_back(const_int64_6);
const_ptr_5_indices.push_back(const_int64_6);
Constant* const_ptr_5 = ConstantExpr::getGetElementPtr(gvar_array__str, const_ptr_5_indices);
// Global Variable Definitions
gvar_array__str->setInitializer(const_array_4);
// Function Definitions
// Function: foo (func_foo)
{
BasicBlock* label_entry = BasicBlock::Create(mod->getContext(), "entry",func_foo,0);
// Block entry (label_entry)
ReturnInst::Create(mod->getContext(), const_ptr_5, label_entry);
}

Related

initializing string in class using constructor

I am creating a class that has two members string and int
I want to use the constructor to initialize both of these two members to use them.
#pragma once
#include <string>
#include <iostream>
using namespace std;
class donation_1
{
public:
//string name;
const char* name;
int donation_amount;
const static size_t string_size = sizeof(string);
const static size_t int_size = sizeof(int);
donation_1(char* name_1 = "Noname", int amount = 0) : name(name_1), donation_amount(amount) {};
};
int main()
{
fstream file;
file.open("donation_total1.txt", ios_base::app);
if (file.is_open())
{
donation_1("xxxx", 20).writedata(file);
donation_1("yyyy", 30).writedata(file);
donation_1("zzzz", 40).writedata(file);
donation_1("MMMM", 50).writedata(file);
donation_1("BBBB", 60).writedata(file);
file.close();
}
else
{
cout << "file couldn't be opened" << endl;
}
return 0;
}
I want to use the constructor to initialize the class variables which I will be using to update a file, however, what I am getting is this error. this error is regarding initializing the string class member.
Severity Code Description Project File Line Suppression State
Error (active) E0310 default argument of type "const char *" is incompatible with parameter of type "char *" Stream_File_Lab D:\INVSPRIVATE\C++\Projects\Stream_File_Lab\donation_1.h 17
The error message is makes it pretty clear. The variable 'name' is declared as const char* but the value being assigned to it is only char* i.e. the const-ness is missing, hence the type incompatibility error throws up.
Please, google for pointer to a const value and how to use them.
Maybe check this tutorial

Converting between WinRT HttpBufferContent and unmanaged memory in C++cx

As part of a WinRT C++cx component, what's the most efficient way to convert an unmanaged buffer of bytes (say expressed as a std::string) back and forth with a Windows::Web::Http::HttpBufferContent?
This is what I ended up with, but it doesn't seem very optimal:
std::string to HttpBufferContent:
std::string m_body = ...;
auto writer = ref new DataWriter();
writer->WriteBytes(ArrayReference<unsigned char>(reinterpret_cast<unsigned char*>(const_cast<char*>(m_body.data())), m_body.length()));
auto content = ref new HttpBufferContent(writer->DetachBuffer());
HttpBufferContent to std::string:
HttpBufferContent^ content = ...
auto operation = content->ReadAsBufferAsync();
auto task = create_task(operation);
if (task.wait() == task_status::completed) {
auto buffer = task.get();
size_t length = buffer->Length;
if (length > 0) {
unsigned char* storage = static_cast<unsigned char*>(malloc(length));
DataReader::FromBuffer(buffer)->ReadBytes(ArrayReference<unsigned char>(storage, length));
auto m_body = std::string(reinterpret_cast<char*>(storage), length);
free(storage);
}
} else {
abort();
}
UPDATE: Here's the version I ended up using (you can trivially create a HttpBufferContent^ from an Windows::Storage::Streams::IBuffer^):
void IBufferToString(IBuffer^ buffer, std::string& string) {
Array<unsigned char>^ array = nullptr;
CryptographicBuffer::CopyToByteArray(buffer, &array); // TODO: Avoid copy
string.assign(reinterpret_cast<char*>(array->Data), array->Length);
}
IBuffer^ StringToIBuffer(const std::string& string) {
auto array = ArrayReference<unsigned char>(reinterpret_cast<unsigned char*>(const_cast<char*>(string.data())), string.length());
return CryptographicBuffer::CreateFromByteArray(array);
}
I think you are making at least one unnecessary copy of your data in your current approach for HttpBufferContent to std::string, you could improve this by accessing the IBuffer data directly, see the accepted answer here: Getting an array of bytes out of Windows::Storage::Streams::IBuffer
I think it's better to use smart pointer (no memory management needed) :
#include <wrl.h>
#include <robuffer.h>
#include <memory>
using namespace Windows::Storage::Streams;
using namespace Microsoft::WRL;
IBuffer^ buffer;
ComPtr<IBufferByteAccess> byte_access;
reinterpret_cast<IInspectable*>(buffer)->QueryInterface(IID_PPV_ARGS(&byte_access));
std::unique_ptr<byte[]> raw_buffer = std::make_unique<byte[]>(buffer->Length);
byte_access->Buffer(raw_buffer.get());
std::string str(reinterpret_cast<char*>(raw_buffer.get())); // just 1 copy

How to add timeout to FLTK pop-up dialog

I am using FLTK library and have used a pop-up function fl_input() from Fl_ask.h. I want a feature that if the user doesn't input and data for 3 seconds, the function should return. How can I make this function return without pressing OK or cancel. Is there anyway to get a handle to this pop-up dialog? This is the code I'm using
const char *message = "Enter name here";
Fl::lock();
char *c = (char*)fl_input(message, "");
if(c == NULL)
c = "";
Fl::unlock();
You can't do this easily using fl_input because there is no handle to the window. Have a look at the fl_input source in src/fl_ask.cxx. You will see it calls input_innards. If you track through to input_innards, you'll see that it calls innards. If you then follow innards, you will find a while loop which reads
while (message_form->shown()) Fl::wait();
Make a copy of fl_ask.cxx, say timed_ask.cxx. Make all the fl_ routines static. Change fl_input as follows:
const char* timed_input(double timeout, const char *fmt, const char *defstr, ...) {
if (avoidRecursion) return 0;
va_list ap;
va_start(ap, defstr);
const char* r = timed_input_innards(timeout, fmt, ap, defstr, FL_NORMAL_INPUT);
va_end(ap);
return r;
}
Make a copy of input_innards and rename the new one to timed_input_innards (this keeps the other fl_routines happy unless you want to delete them).
static const char* timed_input_innards(double timeout, const char* fmt, va_list ap,
const char* defstr, uchar type) {
...
int r = timed_innards(timeout, fmt, ap, fl_cancel, fl_ok, 0);
...
Make a copy of innards and rename the new one to timed_innards
static int timed_innards(double timeout, const char* fmt, va_list ap,
const char *b0,
const char *b1,
const char *b2)
{
...
Fl::add_timeout(timeout, hide_form, message_form);
while (message_form->shown()) Fl::wait();
...
}
Add the timeout routine
void hide_form(void* data)
{
// You could do this or use message_form directly
Fl_Window* form = reinterpret_cast<Fl_Window*>(data);
form->hide();
}
This will cause message_form->shown() to be false and exit the while loop.

Initial assignment a Char Array using a Function in C

as we know it in C, a string defining is,
char string[] = "Hello World";
That is OK,
But I want to use a function and at initial same up,
I tried those, For example;
char * to_string()
{
return "Hello World";
}
Or;
char * to_String(void) // Function
{
char buff[16];
sprintf(buff, "%s", "Hello World");
return buff;
}
main() // main function
{
char Initial_String[] = to_String();
}
How to make this or any idea same another way.
I find what I dont send address of char Initial_String[] to fill into. No. is there Another method.
Thanks.
When you compile this, atleast in GCC, it will give you the following warning:
b.c:9: warning: function returns address of local variable
Why? Because buff[] is a local variable of function to_string(). Its scope is only inside the function to_string(). main() does not have any access to this variable. Try making buff[] a global variable instead.
Second problem: char Initial_String[] = to_String(); cannot be assigned value in this way. to_string() returns a char pointer, hence assign the value thus:
char *Initial_String = to_String();
The code below will work:
char buff[16];
char* to_String(void) // Function
{
//char buff[16]; /*this is a local variable*/
sprintf(buff, "%s", "Hello World");
return buff;
}
int main(void) // main function
{
char *Initial_String = to_String();
printf("%s", Initial_String);
return 0;
}
Yes You are right about local buffer mismake,
But This is not my wanting,
if I edit some differently,
char buff[16];
char* to_String(void) // Function
{
//char buff[16]; /*this is a local variable*/
sprintf(buff, "%s", "Hello World");
return buff;
}
int main(void) // main function
{
char *Initial_String_1 = to_String();
char *Initial_String_2 = to_String();
char *Initial_String_3 = to_String();
printf("%s", Initial_String_1 );
printf("%s", Initial_String_2 );
printf("%s", Initial_String_3 );
in this case, all strings will be same, because They have same buffer address,
I want to open the topic little more.
struct
{
long aaa;
short bbb;
int ccc;
char ddd;
.
.
. // the list goes on
}elements;
typedef struct
{
int lengt;
int *adress;
char name[10];
}_list;
char* to_String(long variable) // Function
{
sprintf(buff, "%ld", variable);
return buff;
}
int main (void)
{
_list My_List[] = {
{ sizeof(elements.aaa), &elements.aaa , to_string( elements.aaa) },
{ sizeof(elements.bbb), &elements.bbb , to_string( elements.bbb) },
{ sizeof(elements.ccc), &elements.ccc , to_string( elements.ddd) },
.
.
. //// the list goes on
};
I do not know, Do I make myself clear.
Here, string must be filled into name array, without assigning it the address.
I may have syntax mistake. the code is not tested with compiler. the idea is for illustrative purposes only.
I am trying to find a method for The purpose.
Thanks.

std::string.c_str() returning a weird characters

In my project, I use to load textures by specifying its file name. Now, I made this function const char* app_dir(std::string fileToAppend); that returns the mains argv[0] and change the application name by the fileToAppend. Since I cannot make the string manipulation easy with a char*, I use the std::string. My texture loader takes a const char* for file name so need to switch back to c_str(), now it generates a sequence of ASCII symbol characters (bug). I already fix the problem by changing the return type of the app_dir() to std::string. But why is that happening?
EDIT
sample code:
//in main I did this
extern std::string app_filepath;
int main(int argc, char** arv) {
app_filepath = argv[0];
//...
}
//on other file
std::string app_filepath;
void remove_exe_name() {
//process the app_filepath to remove the exe name
}
const char* app_dir(std::string fileToAppend) {
string str_app_fp = app_filepath;
return str_app_fp.append(fileToAppend).c_str();
//this is the function the generates the bug
}
I already have the functioning one by changing its return type to std::string as I said earlier.
A big no no :) returning pointer to local objects
return str_app_fp.append(fileToAppend).c_str();
Change your function to
std::string app_dir(const std::string& fileToAppend) {
string str_app_fp = app_filepath + fileToAppend;
return str_app_fp;
}
And on the return value use c_str()
When you using function const char* app_dir(std::string fileToAppend); you get pointer to the memory that allocated on the stack and already deleted when the function ends.

Resources