我的项目让我使用C++Windows RPC将图像从客户端上传到服务器。我以前不使用 WIN RPC,所以我尝试了一些示例,包括向服务器发送基本的"Hello world"消息,但最大的问题是函数无法发送包含"\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
);
我的客户端核心代码(它包含所有需要的标头(是
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);
}
服务器端与客户端几乎相同,我在服务器中使用断点进行调试,但服务器端无法获取无符号字符数组。我认为这是因为我在 MIDL 中的函数只能发送以空结尾('\0'(字符串结尾的 char 数组?我尝试设置数组长度或字符指针的大小,但仍然无法将"\0"无符号字符传输到服务器。
根据 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 ' ' too
Analyze(achInOut, &cbSize);
/* server */
Analyze(char * str, long * pcbSize)
{
...
*pcbSize = strlen(str) + 1; // transmit ' ' too
return;
}
我认为,这个msdn链接会对你有所帮助。
你必须使用OpenCV来读取图像数据吗?由于这篇文章尚未关闭,您可以尝试这种替代方法以二进制模式打开图像文件(也适用于文本文件(,然后将数据读取/保存到浮点数组中,将其发送到服务器。我写了一个简单的演示。它可以工作并避免字符串的空终止符问题。
寄件人:
//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);