如何通过protoc.exe编译C++ 的Proto文件生成C#的.proto文件

博主最近在使用谷歌框架的proto,想在unity下自动生成可用的.proto文件,进行轻量化传输。但不想自己去一个个的生成。所以,找了很多的办法,后来发现可以通过protoc.exe进行生成,但是只能单个命令行进行生成,无法批量编译出.proto文件。后来经过多方尝试,使用Unity框架可以很容易的批量生成proto文件。

一、下载.proto程序

从官网地址选择自己想要的版本,然后下下来放到Unity工程可访问的指定目录,例如:ProtoGen目录

二、将想要转换的proto所有文件打包放在一个文件夹下,注意有依赖 的一定要都放在文件夹下,避免转换时找不到定义的情况出现

三、调用编译函数,如果提示有错误自行解决,没有报错的话,就可以在对应的生成目录找到C#可用的对应的protobuff文件了。

具体代码如下:

public void GenProtoCSFile()
        {
            string protogen = Application.streamingAssetsPath + "/ProtoGen/protoc.exe";
            string protoDir = Application.streamingAssetsPath + "/ProtoGen/Proto";
            List cmds = new List();
            if (!Directory.Exists(protoDir))
            {
                Debug.LogError("不存在Proto文件夹 path:"+ protoDir);
                return;
            }
            DirectoryInfo folder = new DirectoryInfo(protoDir); // Proto所在路径
            FileInfo[] files = folder.GetFiles("*.proto", SearchOption.AllDirectories);
            Debug.LogError("protofile size:" + files.Length);
            string outDir = Path.Combine(Application.streamingAssetsPath, "AssetBundles") + "/ProtoGen/OutDir";
            if (!Directory.Exists(outDir)) // CSharp 输出路径
            {
                Directory.CreateDirectory(outDir);
            }
            foreach (FileInfo file in files)
            {
                string cmd = protogen + " --csharp_out=" + outDir + " -I " + protoDir + " " + file.FullName;
                cmds.Add(cmd);
            }
            Cmd(cmds);
            AssetDatabase.Refresh();
        }

        public void Cmd(List cmds)
        {
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.WorkingDirectory = ".";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardInput = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.RedirectStandardError = true;
            process.OutputDataReceived += OutputHandler;
            process.ErrorDataReceived += ErrorDataHandler;
            process.Start();
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            for (int i = 0; i < cmds.Count; i++)
            {
                process.StandardInput.WriteLine(cmds[i]);
            }
            process.StandardInput.WriteLine("exit");
            process.WaitForExit();
        }

        private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            if (!string.IsNullOrEmpty(outLine.Data))
            {
                Debug.Log(outLine.Data);
            }
        }

        private void ErrorDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            if (!string.IsNullOrEmpty(outLine.Data) && !outLine.Data.Contains("warning:"))
            {
                Debug.LogError(outLine.Data);
            }
        }

你可能感兴趣的:(c++,c#,unity)