从c+发送图像+;在rabbitmq中,使用到c的协议缓冲区# 我想用RabBMQ和协议缓冲区将C++图像中的图像发送到C项目。我正在用opencv从文件中读取图像,并将其保存到矩阵中。问题是如何将图像发送到c#项目?我应该将矩阵转换为字节数组还是字符串?以及如何在c#项目中声明类型

从c+发送图像+;在rabbitmq中,使用到c的协议缓冲区# 我想用RabBMQ和协议缓冲区将C++图像中的图像发送到C项目。我正在用opencv从文件中读取图像,并将其保存到矩阵中。问题是如何将图像发送到c#项目?我应该将矩阵转换为字节数组还是字符串?以及如何在c#项目中声明类型,c#,c++,opencv,rabbitmq,protocol-buffers,C#,C++,Opencv,Rabbitmq,Protocol Buffers,我有一个LPRResult.proto文件: syntax = "proto2" package ProtoBufLPR; message LPRResult { required string LicencsePlate = 1; required bytes Image = 2; } 阅读图像并发送信息: using byte = unsigned char; int sendMessage() { Mat image; image = imread("/home

我有一个
LPRResult.proto
文件:

syntax = "proto2"
package ProtoBufLPR;

message LPRResult {
   required string LicencsePlate = 1;
   required bytes Image = 2;
}
阅读图像并发送信息:

using byte = unsigned char;
int sendMessage() {

 Mat image;
    image = imread("/home/capture4.jpeg", CV_LOAD_IMAGE_COLOR);   // Read the file

    ProtobufLPR::LPRResult lprResult;

    //convert to byte array
    int size = image.total() * image.elemSize();
    byte * bytes = new byte[size];  // you will have to delete[] that later
    std::memcpy(bytes, image.data, size * sizeof(byte));

    lprResult.set_image(bytes, sizeof(byte));

    lprResult.set_licenseplatenumber("1234567");

    SimplePocoHandler handler("10.0.0.6", 5672);

    AMQP::Connection connection(&handler, AMQP::Login("guest", "guest"), "/");
    AMQP::Channel channel(&connection);

    channel.onReady([&]()
    {
        if(handler.connected())
        {

            int size = lprResult.ByteSize();
            char* array = new char[size];
            lprResult.SerializeToArray(array, size);

            channel.publish("", "hello", array);
            std::cout << " [x] Sent 'Hello World!'" << std::endl;
            handler.quit();
        }
    });
}
这是我的c#反序列化代码:

using ProtoBuf;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.IO;
using System.Text;


namespace LPRRabbitMq
{
    class Program
    {
        static void Main(string[] args)
        {

            var factory = new ConnectionFactory()
            {
                HostName = "10.0.0.6",
                UserName = "guest",
                Password = "guest",
                VirtualHost = "/",
                Port = 5672
            };

            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: "hello",
                                     durable: false,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);


                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {

                    LPRResult result;

                    using (var stream = new MemoryStream(ea.Body))
                    {
                       result = Serializer.Deserialize<LPRResult>(stream);

                        Console.WriteLine(result.LicensePlateNumber);
                    }

                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    Console.WriteLine(" [x] Received {0}", message);
                };
                channel.BasicConsume(queue: "hello",
                                     autoAck: true,
                                     consumer: consumer);

                Console.WriteLine(" Press [enter] to exit.");
                Console.ReadLine();
            }
        }
    }
}
使用ProtoBuf;
使用RabbitMQ.Client;
使用RabbitMQ.Client.Events;
使用制度;
使用System.IO;
使用系统文本;
名称空间LPRRabbitMq
{
班级计划
{
静态void Main(字符串[]参数)
{
var factory=新连接工厂()
{
HostName=“10.0.0.6”,
UserName=“guest”,
Password=“guest”,
VirtualHost=“/”,
端口=5672
};
使用(var connection=factory.CreateConnection())
使用(var channel=connection.CreateModel())
{
channel.QueueDeclare(队列:“hello”,
持久性:错误,
独家:假,,
自动删除:false,
参数:null);
var消费者=新事件基本消费者(渠道);
消费者.已接收+=(型号,ea)=>
{
LPRResult结果;
使用(变量流=新内存流(ea.Body))
{
结果=序列化程序。反序列化(流);
控制台。写入线(结果。许可证号码);
}
变量体=ea.body;
var message=Encoding.UTF8.GetString(body);
WriteLine(“[x]收到{0}”,消息);
};
channel.BasicConsume(队列:“hello”,
autoAck:是的,
消费者:消费者),;
Console.WriteLine(“按[enter]退出”);
Console.ReadLine();
}
}
}
}

我能看看c#反序列化代码吗?这类事情通常是在数据到达序列化程序之前传输或处理数据时发生的错误。如果您有原始有效负载的捕获,您可以使用来测试它是否与您期望的匹配。您也可以使用从.proto生成protobuf网络类型,但是您显示的类看起来很好(谢天谢地,这是一个简单的场景)。我的另一个怀疑是,是否有一些特定于rabbit片段的有效负载的“包装器”。如果您有演示数据(可以在公共互联网上共享的虚拟字符串和图像),并且您可以将有效负载发布为十六进制、base-64或某个原始文件,我很乐意看一看。但正如我所说的,我想看到的第一件事是你的c代码正在反序列化调用另一件事是:rabbit知道它正在发送二进制/它是二进制安全的吗?若它只需要文本,那个么它可能会在每一端通过类似utf-8的编码来运行它,这会让整个过程变得一团糟payload@MarcGravell我更新了这个问题,如果你发送二进制数据,为什么你在C++侧使用char *?
using ProtoBuf;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.IO;
using System.Text;


namespace LPRRabbitMq
{
    class Program
    {
        static void Main(string[] args)
        {

            var factory = new ConnectionFactory()
            {
                HostName = "10.0.0.6",
                UserName = "guest",
                Password = "guest",
                VirtualHost = "/",
                Port = 5672
            };

            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: "hello",
                                     durable: false,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);


                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {

                    LPRResult result;

                    using (var stream = new MemoryStream(ea.Body))
                    {
                       result = Serializer.Deserialize<LPRResult>(stream);

                        Console.WriteLine(result.LicensePlateNumber);
                    }

                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    Console.WriteLine(" [x] Received {0}", message);
                };
                channel.BasicConsume(queue: "hello",
                                     autoAck: true,
                                     consumer: consumer);

                Console.WriteLine(" Press [enter] to exit.");
                Console.ReadLine();
            }
        }
    }
}