简体   繁体   中英

how to use win RPC to send terminated char array(use to upload image from client to server)

My project let me use C++ Windows RPC to upload image from client to server. I do not use WIN RPC before, So I tried some examples include send basic "Hello world" Message to server, but the huge issue is the function can't send unsigned char* include '\\0'. I appreciate someone can give me some suggestion to solve this problem.


I use opencv 3.2 to read image to Mat, and I can get Mat data and use memcpy to copy the Mat.data then create a new image in local client. But when I send Mat.data to server, the first of characters in the Mat.data is '\\0'. All the Mat.data don't send to server.

My MIDL core code(I have defined uuid and version) is

void Output(
    [in, out, size_is(1048576), string] unsigned char szString[]
);
void Output1(
    [in, string] unsigned char* szString1
);

My Client core code(It has include all require header) is

Mat I = imread("U:\\normal.jpg", IMREAD_ANYDEPTH);
if (I.empty())
{
    std::cout << "!!! Failed imread(): image not found" << std::endl;
    // don't let the execution continue, else imshow() will crash.
}
if (!I.data) {
    std::cout << "can't open or find image" << std::endl;
    //return -1;
}
Mat out;
I.convertTo(I, CV_32F);
I = (I.reshape(0, 1)); // to make it continuous
char tr[512*512*4];
memcpy_s(tr, 512 * 512 * 4, I.data, 512*512 * 4);
//snprintf(tr, 512*512*4,"%s", I.data);
out = Mat(512,512, CV_32F, &tr[0]);
namedWindow("Display window", CV_WINDOW_AUTOSIZE);// Create a window for display.
imshow("Display window", out);
waitKey(5000);

.....

RpcTryExcept
{
    std::clog << "Calling Open" << std::endl;
    output((unsigned char* )tr);
    //output1((unsigned char* )tr);
}

Server side is pretty same with client, I use break point in server to debug, but server side can't get the unsigned char array. I think it's because my function in MIDL just can send the char array, which is end by a null terminated('\\0') string? I tried set the array length or the size of the char pointer but still can't transmit '\\0' unsigned char to server.

From the MSDN explanation, when you sending array to stub you need to specify length_is also in your midl code.

The [ size_is] attribute indicates the upper bound of the array while the [ length_is] attribute indicates the number of array elements to transmit. In addition to the array, the remote procedure prototype must include any variables representing length or size that determine the transmitted array elements (they can be separate parameters or bundled with the string in a structure). These attributes can be used with wide-character or single-byte character arrays just as they would be with arrays of other types.

And

As an [in] parameter, achInOut must point to valid storage on the client side. The developer allocates memory associated with the array on the client side before making the remote procedure call. The stubs use the [size_is] parameter strsize to allocate memory on the server and then use the [length_is] parameter pcbSize to transmit the array elements into this memory. The developer must make sure the client code sets the [length_is] variable before calling the remote procedure.

Their example of character array sending:

#define STRSIZE 500 //maximum string length

void Analyze(
  [in, out, length_is(*pcbSize), size_is(STRSIZE)] char  achInOut[],
  [in, out]  long *pcbSize);


/* client */ 
char achInOut[STRSIZE];
long cbSize;
...
gets_s(achInOut, STRSIZE);       // get patient input
cbSize = strlen(achInOut) + 1;   // transmit '\0' too
Analyze(achInOut, &cbSize);

/* server */ 
Analyze(char * str, long * pcbSize)
{
   ...
   *pcbSize = strlen(str) + 1; // transmit '\0' too
   return;
}

I think, this msdn link will help you.

Do you have to use OpenCV to read image data? Since this post has not been closed, you can try this alternative way to open image file(it works for text file as well) in binary mode, then read/save data into a float array, send it to server. I wrote a simple demo. It works and avoid the null-terminator problem for string.

Sender:

//Open file
char filename[] = "demo1.jpg";
FILE *fp = fopen(filename,"rb");

//Get File size
fseek(fp, 0, SEEK_END);
int size = ftell(fp);
fseek(fp, 0, SEEK_SET);

//Read file to buffer
float *img = new float[size];
fread(img, 1, size, fp);

RpcTryExcept
{   
    //Call your function pre-defined in IDL here to send float arry  
}

Receiver:

FILE *fp = fopen((char *)fileName, "wb");
int recvByte = fwrite(img, 1, size, fp);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM