How to transmit ASCII by WriteFile function - visual-c++

I am writing following codes to transmit ASCII(62), ASCII(42),ASCII(62),ASCII(112) through serial port.
DWORD written;
WriteFile(serialHandle,">>p",strlen(">>p"),&written,NULL);
But right now I want to transmit ASCII(4).ASCII(0) also, but I don't know how to write them into char type.
If I write: WriteFile(serialHandle, 4,1, &written, NULL); the VC++ system will give me an error message.
Would you please help me to re-write WriteFile function to meet my requirement?

You do not have to use " quotes with WriteFile. Seems like you should learn to use arrays.
char buf[2];
buf[0] = 4;
buf[1] = 0;
WriteFile(serialHandle, buf, 2, &written, NULL);

Related

(epbf) Unable to use string.h apis on string that probe read from kernel

When I tried to do some string operations (strlen, strcpy and strtok) today, I found it is unable to use those string.h apis on string probe read from kernel.
It will raise unknown opcode error on python bcc/bpf and raise libbpf: failed to find BTF for extern 'strlen' on libbpf.
A pseudo code I tried as follows:
u64 ptr = PT_REGS_PARMX(regs);
char str1[10] = {};
char str2[10] = "test";
bpf_probe_read_kernel(str1, sizeof(str1), (const void *) ptr);
u64 len = strlen(str1); // error will raise here
len = strlen(str2); // but this is ok if string not read from kernel
Although strlen I could implement in:
u64 len = 0;
for(len; len < sizeof(str1); len++){
if (str1[len] == '\0') break;
}
I still wonder that why it is unable to use string.h apis
and how could make it able to use.
You can't call arbitrary kernel functions from BPF bytecode.
The reason it works for str2 is because it's a constant and the compiler therefore optimizes it to 4 without needing to call strlen.
If you need to compute the length of a string, you need to implement strlen() yourself or to copy one of the kernel's implementations. Note that in general, it is not recommended to perform computation on strings in BPF; that's a job better left to the userspace counterpart.

How to send an int over uint8_t data?

I'm using the RadioHead Packet Radio library from airspayce.com. In the example (nrf24_reliable_datagram_client & server) they let two nodes communicate with each other by sending strings back and forth. Now I want to send an int instead of a string there, and do something with this data. This is what they do in the example:
Define the buf byte.
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
This function receives the data:
manager.recvfromAckTimeout(buf, &len, 500, &from)
Print the buf variable.
Serial.print((char*)buf);
So far so good.Now I want to do something like:
int value = (char*)buf;
Or:
char value[10] = { (char*)buf };
But then I get:
invalid conversion from 'char*' to 'int' (or to 'char'...)
Next to that, on the other side where I'm sending the data, I have:
uint8_t data[] = { analogRead(A0) };
When I'm printing this data on the receiver side, using the code from the first question, I get weird characters. So I thought, let's try:
Serial.print((char*)buf, DEC); // or BYTE
But then I get:
call of overloaded 'print(char*, int)' is ambiguous
What am I doing wrong? Thanks in advance!
You can't just assign an array to an integer and hope that it merges the elements together for you - for example, how does it know how to merge them?
For converting a uint16_t to a uint8_t[2] array you would want to do something like this:
uint16_t analog = analogRead(A0); //read in as int.
uint8_t data[2] = {analog, (analog >> 8)}; // extract as {lower byte, upper byte)
Serial.write(data,2); //write the two bytes to the serial port, lower byte first.
You could do it in other ways like using a union of a uint16_t with an array of two uint8_t's, but the above way is more portable. You could also do it by type casting the pointer to an int, however if one end uses big endian and the other uses little endian, that won't work unless you flip the data around in the array as you are receiving it.
For the receiver end, you would have:
uint8_t data[2];
...
... //whatever you do to receive the bytes that were sent over serial.
...
//Now assuming that data[] contains the received bytes where:
//data[0] was the first in (lower byte) and data[1] was the second in (upper byte)
uint16_t merged = (data[1] << 8) | data[0]; //merge them back together
Hopefully that helps.
Also, the 'overloaded prototype' is saying that no function exists which takes that particular set of input variables. From the print class header you will find there is however this prototype:
write(const uint8_t *buffer, size_t size);
which does what you want - print a specified number of uint8_t's from an array.

How to send integer as a string with WriteFile for serialport

I want to send an integer as a string buffer to a serial port with WriteFile. This data value is result from the sensor, this data max has 2 characters.
I have tried to convert with itoa
for example:
DWORD nbytes;
int a,b,c;
a=10;
char *tempa ="";
tempa = itoa(a, tempa,0);
if(!WriteFile( hnd_serial, a, 2, &nbytes, NULL )){MessageBox(L"Write Com Port fail!");return;}
This code is not working.
Unhandled exception at 0x1024d496 (msvcr100d.dll) in ENVSConfig.exe: 0xC0000094: Integer division by zero.
Also I have tried the suggestion from this website:
convert int to string but still does not working to.
Is there any clue to do this?
You are not using itoa properly, you need to allocate space for your string, you need to provide a proper radix (this is where your divide-by-zero error is happening) and finally you need to use the buffer, not your original a value, as the buffer in your write.
Try the following:
DWORD nbytes;
int a,b,c;
a = 10;
char tempa[64]; // Randomly picked 64 characters as the max size
itoa(a, tempa, 10);
if(!WriteFile(hnd_serial, tempa, 2, &nbytes, NULL))
{
MessageBox(L"Write Com Port fail!");
return;
}

Convert hex to int

I've seen lots of answers to this, but I cannot seem to get any to work. I think I'm getting confused between variable types. I have an input from NetworkStream that is put a hex code into a String^. I need to take part of this string, convert it to a number (presumably int) so I can add some arithemetic, then output the reult on the form. The code I have so far:
String^ msg; // gets filled later, e.g. with "A55A6B0550000000FFFBDE0030C8"
String^ test;
//I have selected the relevant part of the string, e.g. 5A
test = msg->Substring(2, 2);
//I have tried many different routes to extract the numverical value of the
//substring. Below are some of them:
std::stringstream ss;
hexInt = 0;
//Works if test is string, not String^ but then I can't output it later.
ss << sscanf(test.c_str(), "%x", &hexInt);
//--------
sprintf(&hexInt, "%d", test);
//--------
//And a few others that I've deleted after they don't work at all.
//Output:
this->textBox1->AppendText("Display numerical value after a bit of math");
Any help with this would be greatly appreciated.
Chris
Does this help?
String^ hex = L"5A";
int converted = System::Convert::ToInt32(hex, 16);
The documentation for the Convert static method used is on the MSDN.
You need to stop thinking about using the standard C++ library with managed types. The .Net BCL is really very good...
Hope this helps:
/*
the method demonstrates converting hexadecimal values,
which are broken into low and high bytes.
*/
int main(){
//character buffer
char buf[1];
buf[0]= 0x06; //buffer initialized to some hex value
buf[1]= 0xAE; //buffer initialized to some hex value
int number=0;
//number generated by binary shift of high byte and its OR with low byte
number = 0xFFFF&((buf[1]<<8)|buf[0]);
printf("%x",number); //this prints AE06
printf(“%d”,number); //this prints the integer equivalent
getch();
}

How to get size of file in visual c++?

Below is my code. My problem is, my destination file always has a lot more strings than the originating file. Then, inside the for loop, instead of using i < sizeof more, I realized that I should use i < sizeof file2 . Now my problem is, how to get the size of file2?
int i = 0;
FILE *file2 = fopen(LOG_FILE_NAME,"r");
wfstream file3 (myfile, ios_base::out);
// char more[1024];
char more[SIZE-OF-file2];
for(i = 0; i < SIZE-OF-file2 ; i++)
{
fgets(more, SIZE-OF-file2, file2);
file3 << more;
}
fclose(file2);
file3.close();
The most basic way is to fseek to the end of the file and to use ftell to give you the offset. The other (stat) functions also do this, but they're not cross-platform. Of course, if you want your code rot in hell, you could also use GetFileSize().
fseek(file, 0, SEEK_END);
off_t offset = ftell(file);
fseek(file, 0, SEEK_SET);
Every time you refer to C as Visual C, or C++ as Visual C++ I die a little.
You can do this using GetFileSize(). By reading the size of the file from the filesystem, you will avoid a lot of unnecessary computation. This can also be done with _stat(), or on unix it would just be stat().
Here is the definition:
DWORD WINAPI GetFileSize(
__in HANDLE hFile,
__out_opt LPDWORD lpFileSizeHigh
);
Doc for GetFileSize:
http://msdn.microsoft.com/en-us/library/aa364955%28VS.85%29.aspx
Alternatively you might want to use _stat()
Doc for stat:
http://msdn.microsoft.com/en-us/library/14h5k7ff%28VS.80%29.aspx

Resources