how to convert long int to char - winapi

#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
HANDLE hPort = CreateFile("COM2",
GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
DCB dcb;
bool writebyte(char*data)
{
DWORD byteswritten;
if (!GetCommState(hPort,&dcb))
{
printf("\nSerial port can't be open\n");
return false;
}
dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(hPort,&dcb))
return false;
bool retVal = WriteFile(hPort,data,1,&byteswritten,NULL);
return retVal;
}
int ReadByte()
{
int Val;
BYTE Byte;
DWORD dwBytesTransferred;
DWORD dwCommModemStatus;
if (!GetCommState(hPort,&dcb))
return 0;
SetCommMask(hPort,EV_RXCHAR | EV_ERR);
WaitCommEvent (hPort,&dwCommModemStatus,0);
if (dwCommModemStatus & EV_RXCHAR)
ReadFile (hPort,&Byte,1,&dwBytesTransferred,0);
Val = Byte;
return Val;
}
int main() {
POINT p;
int x;
int y;
int z;
while(0==0){
GetCursorPos(&p);
x = p.x;
y = p.y;
HDC hDC;
hDC = GetDC(NULL);
cin >> z;
cout << GetPixel(hDC, x, y) << endl;
Sleep(z);
ReleaseDC(NULL, hDC);
char data = GetPixel(hDC, x, y);
if (writebyte(&data))
cout <<" DATA SENT.. " << (int)data<< "\n";
}
}
in the part of sending data through serial communication, instead of sending the data as GetPixel(hDC, x, y), it only sends the value "-1" . I was thinking it is because char is only for small integers and the output I was giving is a very very long number. I tried to change it to long int but i still get the same result. That it only sends "-1". I thought that the solution might be converting char to long int or long int to char before sending the data but I don't know how..can someone help me?

Why do you use hDC after releasing it?
ReleaseDC(NULL, hDC);
char data = GetPixel(hDC, x, y);
GetPixel will return -1 (CLR_INVALID) in case of an error (see MSDN).
And, by the way, a COLORREF is not a char, so you lose Information when storing the return value of GetPixel in char data. You should store the complete COLORREF and send/receive all of it's bytes (so send/receive sizeof(COLORREF) bytes).
Also be aware of byte order. If you are transferring multi byte data between two machines then you must assure that both agree on the order of the bytes. If for example one machine is little endian and the other big endian, then they store COLORREF with different byte order in memory. One is storing the COLORREF 0x00BBGGRR in memory as { 0, 0xbb, 0xgg, 0xrr } whereas the other is storing it as { 0xrr, 0xgg, 0xbb, 0 }. So you need to define a transmit byte order which both sides use independant of their host byte order. If you don't want to invent the wheel new, you can take a look at network byte order and reuse that. Socket API gives you some functions like ntohl and htonl which help you in converting from host byte order to network byte order and vice versa.

Related

kernel change MMAP memory but user space not change

Goal: I want to transfer data from kernel driver to user space app real time.
Method: I use mmap to connect kernel buffer_K and user buffer_U. When I change write data to K, the U will be changed also.
Problem: When I changed the buffer_K, use mmcpy(buffer_k, buffer_another, length), the buffer_K changed, but the buffer_U not change, my change frequency is 4ms.
This is my code
In kernel space, if kernel work done, it will trigger a signal to notice user space.
static uint8_t *mmap_buffer;
mmap_buffer = (uint8_t *)kmalloc(ads1299.samp_size * ads1299.buff_size, GFP_KERNEL);
int event()
{
memcpy(mmap_buffer, ads1299.buff_a, ads1299.buff_size * ads1299.samp_size);
SEND_SIGNAL_TO_APP;
}
int ads1299_mmap(struct file *flip, struct vm_area_struct *vma)
{
unsigned long page;
unsigned long start = (unsigned long)vma->vm_start;
unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start);
vma->vm_flags |= VM_IO;
vma->vm_flags |= VM_SHARED;
page = virt_to_phys(mmap_buffer);
if(remap_pfn_range(vma,start,page>>PAGE_SHIFT, size, vma->vm_page_prot))
{
return -1;
}
return 0;
}
This is my user code
unsigned char *buffer= NULL;
buffer = (unsigned char*)malloc(charDataLen*sizeof(unsigned char));
buffer = (unsigned char *)mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED, fd, 0);
if(buffer == MAP_FAILED)
{
printf("mmap error\r\n");
return -1;
}
int signal_handle()
{
usebufer(buffer)
}
Could you tell me some suggestion about my problem. Thanks.

C++ & Xcode8.3.3 : Apple Mach-O Linker error

I am working on C++ code to read and write .bmp image.
Below is my code.
However, I encountered some problems that I couldn't fix. enter image description here
I have googled a lot but none of them solve my problem.
Sorry if my coding style doesn't look good to you, I'm new to Xcode and C++.
Please help me.
I will be really appreciated.
#include <iostream>
#include <stdio.h>
#pragma pack(2)
typedef struct // BMP file header structure
{
unsigned short bfType ; // Magic number for file
unsigned int bfSize ; // Size of file
unsigned short bfReserved1 ; // Reserved, usually set to 0
unsigned short bfReserved2 ; // Reserved, usually set to 0
unsigned int bfoffBits ; // Offset to bitmap data
}BITMAPFILEHEADER;
#pragma pack()
typedef struct
{
unsigned int biSize ; // Size of info header
int biWidth ; // Width of image
int biHeight ; // Height of image
unsigned short biPlanes ; // Number of color planes
unsigned short biBitCount ; // Number of bits per pixel
unsigned int biCompression ; // Type of compression to use, 0 if there is no compression
unsigned int biSizeImage ; // Size of image data
int biXPelsPerMeter ; // X pixels per meter
int biYPelsPerMeter ; // Y pixels per meter
unsigned int biClrUsed ; // Number of color used
unsigned int biClrImportant ; // Number of important color
}BITMAPINFOHEADER;
unsigned char *ReadBitmapFile(const char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
FILE* file ; //file pointer
BITMAPFILEHEADER bitmapFileHeader ; //bitmap file header
unsigned char *bitmapimage ; //store image data
int imageIdx = 0 ;
unsigned char tempRGB ; //swap
// open file in read binary mode
file = fopen(filename, "rb");
if (file == NULL)
return NULL;
// read the bitmap file header
fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, file);
// read the bitmap info header
fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER),1,file);
//move file point to the begging of bitmap data
fseek(file, bitmapFileHeader.bfoffBits, SEEK_SET);
//allocate enough memory for the bitmap image data
bitmapimage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
//verify memory allocation
if(!bitmapimage)
{
free(bitmapimage);
fclose(file);
return NULL;
}
// read in the bitmap image data
fread(bitmapimage, bitmapInfoHeader->biSizeImage, 1, file);
//swap the r and b value to get RGB (bitmap is BGR)
for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx+=3){
tempRGB = bitmapimage[imageIdx];
bitmapimage[imageIdx] = bitmapimage[imageIdx + 2];
bitmapimage[imageIdx + 2] = tempRGB;
}
//close file and return bitmap data
fclose(file);
return bitmapimage;
}
BITMAPINFOHEADER bitmapInfoHeader;
unsigned char *bitmapData = ReadBitmapFile("input1.bmp", &bitmapInfoHeader);
By the way, I am using Xcode8.3.3

c alignment of pointers

I'm wondering if it's possible to hint to gcc that a pointer points to an aligned boundary. if I have a function:
void foo ( void * pBuf ) {
uint64_t *pAligned = pBuf;
pAligned = ((pBuf + 7) & ~0x7);
var = *pAligned; // I want this to be aligned 64 bit access
}
And I know that pBuf is 64 bit aligned, is there any way to tell gcc that pAligned points to a 64 bit boundary? If I do:
uint64_t *pAligned __attribute__((aligned(16)));
I believe that means that the address of the pointer is 64 bit aligned, but it doesn't tell the compiler that the what it points to is aligned, and therefore the compiler would likely tell it to do an unaligned fetch here. This could slow things down if I'm looping through a large array.
There are several ways to inform GCC about alignment.
Firstly you can attach align attribute to pointee, rather than pointer:
int foo() {
int __attribute__((aligned(16))) *p;
return (unsigned long long)p & 3;
}
Or you can use (relatively new) builtin:
int bar(int *p) {
int *pa = __builtin_assume_aligned(p, 16);
return (unsigned long long)pa & 3;
}
Both variants optimize to return 0 due to alignment.
Unfortunately the following does not seem to work:
typedef int __attribute__((aligned(16))) *aligned_ptr;
int baz(aligned_ptr p) {
return (unsigned long long)p & 3;
}
and this one does not either
typedef int aligned_int __attribute__((aligned (16)));
int braz(aligned_int *p) {
return (unsigned long long)p & 3;
}
even though docs suggest the opposite.

Inverting an image using MPI

I am trying to invert a PGM image using MPI. The grayscale (PGM) image should be loaded on the root processor and then be sent to each of the s^2 processors. Each processor will invert a block of the given image, and the inverted blocks will be gathered back on the root processor, which will assemble the blocks into the final image and write it to a PGM image. I ran the following code, but did not get any output. The image was read after running the code, but there was no indication of writing the resultant image. Could you please let me know what could be wrong with it?
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <time.h>
#include <string.h>
#include <math.h>
#include <memory.h>
#define max(x, y) ((x>y) ? (x):(y))
#define min(x, y) ((x<y) ? (x):(y))
int xdim;
int ydim;
int maxraw;
unsigned char *image;
void ReadPGM(FILE*);
void WritePGM(FILE*);
#define s 2
int main(int argc, char **argv) {
MPI_Init(&argc, &argv);
int p, rank;
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
const int NPROWS=s; /* number of rows in _decomposition_ */
const int NPCOLS=s; /* number of cols in _decomposition_ */
const int BLOCKROWS = xdim/NPROWS; /* number of rows in _block_ */
const int BLOCKCOLS = ydim/NPCOLS; /* number of cols in _block_ */
int i, j;
FILE *fp;
float BLimage[BLOCKROWS*BLOCKCOLS];
for (int ii=0; ii<BLOCKROWS*BLOCKCOLS; ii++)
BLimage[ii] = 0;
float BLfilteredMat[BLOCKROWS*BLOCKCOLS];
for (int ii=0; ii<BLOCKROWS*BLOCKCOLS; ii++)
BLfilteredMat[ii] = 0;
if (rank == 0) {
/* begin reading PGM.... */
ReadPGM(fp);
}
MPI_Datatype blocktype;
MPI_Datatype blocktype2;
MPI_Type_vector(BLOCKROWS, BLOCKCOLS, ydim, MPI_FLOAT, &blocktype2);
MPI_Type_create_resized( blocktype2, 0, sizeof(float), &blocktype);
MPI_Type_commit(&blocktype);
int disps[NPROWS*NPCOLS];
int counts[NPROWS*NPCOLS];
for (int ii=0; ii<NPROWS; ii++) {
for (int jj=0; jj<NPCOLS; jj++) {
disps[ii*NPCOLS+jj] = ii*ydim*BLOCKROWS+jj*BLOCKCOLS;
counts [ii*NPCOLS+jj] = 1;
}
}
MPI_Scatterv(image, counts, disps, blocktype, BLimage, BLOCKROWS*BLOCKCOLS, MPI_FLOAT, 0, MPI_COMM_WORLD);
//************** Invert the block **************//
for (int proc=0; proc<p; proc++) {
if (proc == rank) {
for (int j = 0; j < BLOCKCOLS; j++) {
for (int i = 0; i < BLOCKROWS; i++) {
BLfilteredMat[j*BLOCKROWS+i] = 255 - image[j*BLOCKROWS+i];
}
}
} // close if (proc == rank) {
MPI_Barrier(MPI_COMM_WORLD);
} // close for (int proc=0; proc<p; proc++) {
MPI_Gatherv(BLfilteredMat, BLOCKROWS*BLOCKCOLS,MPI_FLOAT, image, counts, disps,blocktype, 0, MPI_COMM_WORLD);
if (rank == 0) {
/* Begin writing PGM.... */
WritePGM(fp);
free(image);
}
MPI_Finalize();
return (1);
}
It is very likely MPI is not the right tool for the job. The reason for this is that your job is inherently bandwidth limited.
Think of it this way: You have a coloring book with images which you all want to color in.
Method 1: you take your time and color them in one by one.
Method 2: you copy each page to a new sheet of paper and mail it to a friend who then colors it in for you. He mails it back to you and in the end you glue all the pages you received from all of your friends together to make one colored-in book.
Note that method two involves copying the whole book, which is arguably the same amount of work needed to color in the whole book. So method two is less time-efficient without even considering the overhead of shoving the pages into an envelope, licking the stamp, going to the post office and waiting for the letter to be delivered.
If you look at your code, every transmitted byte is only touched once throughout the whole program in this line:
BLfilteredMat[j*BLOCKROWS+i] = 255 - image[j*BLOCKROWS+i];
The single processor is much faster at subtracting two integers than it is at sending an integer of the wire, therefore one must advise against using MPI for your particular problem.
My suggestion to solve your problem: Try to avoid unneccessary communication whenever possible. Do all processes have access to the file system on which the files are located? You could try reading them directly from the filesystem.

when to use hton/ntoh and when to convert data myself?

to convert a byte array from another machine which is big-endian, we can use:
long long convert(unsigned char data[]) {
long long res;
res = 0;
for( int i=0;i < DATA_SIZE; ++i)
res = (res << 8) + data[i];
return res;
}
if another machine is little-endian, we can use
long long convert(unsigned char data[]) {
long long res;
res = 0;
for( int i=DATA_SIZE-1;i >=0 ; --i)
res = (res << 8) + data[i];
return res;
}
why do we need the above functions? shouldn't we use hton at sender and ntoh when receiving? Is it because hton/nton is to convert integer while this convert() is for char array?
The hton/ntoh functions convert between network order and host order. If these two are the same (i.e., on big-endian machines) these functions do nothing. So they cannot be portably relied upon to swap endianness. Also, as you pointed out, they are only defined for 16-bit (htons) and 32-bit (htonl) integers; your code can handle up to the sizeof(long long) depending on how DATA_SIZE is set.
Through the network you always receive a series of bytes (octets), which you can't directly pass to ntohs or ntohl. Supposing the incoming bytes are buffered in the (unsigned) char array buf, you could do
short x = ntohs(*(short *)(buf+offset));
but this is not portable unless buf+offset is always even, so that you read with correct alignment. Similarly, to do
long y = ntohl(*(long *)(buf+offset));
you have to make sure that 4 divides buf+offset. Your convert() functions, though, don't have this limitation, they can process byte series at arbitrary (unaligned) memory address.

Resources