繁体   English   中英

如何使用Win RPC发送终止的char数组(用于将映像从客户端上传到服务器)

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

我的项目允许我使用C ++ Windows RPC将图像从客户端上传到服务器。 我以前没有使用WIN RPC,所以我尝试了一些示例,包括向服务器发送基本的“ Hello world”消息,但是最大的问题是该函数无法发送未签名的char *包括'\\ 0'。 我感谢有人可以给我一些解决此问题的建议。


我使用opencv 3.2将图像读取到Mat,可以获取Mat数据并使用memcpy复制Mat.data,然后在本地客户端中创建新图像。 但是,当我将Mat.data发送到服务器时,Mat.data中的第一个字符为'\\ 0'。 所有的Mat.data都不会发送到服务器。

我的MIDL核心代码(我已经定义了uuid和版本)是

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

我的客户核心代码(已包含所有require标头)为

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);
}

服务器端与客户端非常相似,我使用服务器中的断点进行调试,但服务器端无法获取未签名的char数组。 我认为这是因为MIDL中的函数只能发送char数组,该数组以null结尾的('\\ 0')字符串结尾吗? 我尝试设置数组长度或char指针的大小,但仍然无法将'\\ 0'无符号char传输到服务器。

根据MSDN的说明,将数组发送到存根时,还需要在midl代码中指定length_is。

[size_is]属性指示数组的上限,而[length_is]属性指示要传输的数组元素的数量。 除了数组之外,远程过程原型还必须包括表示长度或大小的任何变量,这些变量确定传输的数组元素(它们可以是单独的参数,也可以与结构中的字符串捆绑在一起)。 这些属性可以与宽字符或单字节字符数组一起使用,就像与其他类型的数组一样。

作为[in]参数,achInOut必须指向客户端上的有效存储。 在进行远程过程调用之前,开发人员会在客户端上分配与数组关联的内存。 存根使用[size_is]参数strsize在服务器上分配内存,然后使用[length_is]参数pcbSize将数组元素传输到此内存中。 开发人员必须在调用远程过程之前确保客户端代码设置了[length_is]变量。

他们的字符数组发送示例:

#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;
}

我认为,此msdn链接将为您提供帮助。

您必须使用OpenCV读取图像数据吗? 由于此帖子尚未关闭,您可以尝试这种替代方法以二进制模式打开图像文件(它也适用于文本文件),然后将数据读取/保存到float数组中,然后将其发送到服务器。 我写了一个简单的演示。 它可以正常工作,避免了字符串的空终止符问题。

发件人:

//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  
}

接收器:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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