You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从C#调用带数组参数的Python函数并获取返回值

C#进程调用Python函数传递数组参数解决方案

核心思路

由于IronPython无法安装numpy、gurobipy等依赖库,采用进程调用+JSON序列化的方式传递数组参数:C#将数组序列化为JSON字符串传递给Python进程,Python端解析JSON还原为numpy数组,执行函数后再将结果序列化为JSON返回给C#。


步骤1:修改Python脚本,支持命令行参数接收数组

修改原Python函数,添加入口逻辑,从命令行读取JSON格式的points数组及其他参数,执行mclp后输出JSON结果:

import sys
import json
import numpy as np
import gurobipy as gp
from gurobipy import GRB

def mclp(points, K, radius, M):
    n = points.shape[0]
    # 计算距离矩阵
    dist_matrix = np.sqrt(((points[:, np.newaxis] - points)**2).sum(axis=2))
    # 创建模型
    m = gp.Model()
    # 变量
    x = m.addVars(n, vtype=GRB.BINARY, name='x')
    y = m.addVars(n, vtype=GRB.BINARY, name='y')
    # 目标函数
    m.setObjective(gp.quicksum(y[i] for i in range(n)), GRB.MAXIMIZE)
    # 约束
    m.addConstr(gp.quicksum(x[j] for j in range(n)) <= K, name='K')
    for i in range(n):
        m.addConstr(gp.quicksum(x[j] for j in range(n) if dist_matrix[i][j] <= radius) >= y[i], name=f'cover_{i}')
    m.addConstrs(y[i] <= M for i in range(n))
    # 求解
    m.optimize()
    # 返回结果
    selected = [j for j in range(n) if x[j].X > 0.5]
    covered = [i for i in range(n) if y[i].X > 0.5]
    return selected, covered

if __name__ == '__main__':
    # 检查参数数量
    if len(sys.argv) < 4:
        print("参数错误:需传入points数组(JSON字符串)、K、radius、M")
        sys.exit(1)
    # 解析参数
    points_json = sys.argv[1]
    points = np.array(json.loads(points_json))
    K = int(sys.argv[2])
    radius = float(sys.argv[3])
    M = int(sys.argv[4])
    
    # 执行函数并输出结果
    selected, covered = mclp(points, K, radius, M)
    print(json.dumps({'selected': selected, 'covered': covered}))

步骤2:C#端实现进程调用与参数传递

使用Process类启动Python进程,将points数组序列化为JSON字符串作为命令行参数传递,捕获输出并解析结果:

using System;
using System.Diagnostics;
using System.Text;
using System.Collections.Generic;
using Newtonsoft.Json; // 或使用System.Text.Json,需对应调整序列化代码

class PythonCaller
{
    static void Main()
    {
        // 构造输入参数
        double[,] points = new double[,] { { 1.2, 3.4 }, { 5.6, 7.8 }, { 9.0, 2.3 }, { 4.5, 6.7 } };
        int K = 2;
        double radius = 4.0;
        int M = 1;

        // 将二维数组转为可序列化的List<double[]>
        var pointList = new List<double[]>();
        for (int i = 0; i < points.GetLength(0); i++)
        {
            double[] point = new double[points.GetLength(1)];
            for (int j = 0; j < points.GetLength(1); j++)
            {
                point[j] = points[i, j];
            }
            pointList.Add(point);
        }
        string pointsJson = JsonConvert.SerializeObject(pointList);

        // 配置Python进程
        var psi = new ProcessStartInfo
        {
            FileName = "python", // 若为Python3,需改为"python3"或绝对路径(如"C:/Python310/python.exe")
            Arguments = $"\"mclp_script.py\" \"{pointsJson}\" {K} {radius} {M}",
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            UseShellExecute = false,
            CreateNoWindow = true,
            StandardOutputEncoding = Encoding.UTF8,
            StandardErrorEncoding = Encoding.UTF8
        };

        using (var process = Process.Start(psi))
        {
            string output = process.StandardOutput.ReadToEnd();
            string error = process.StandardError.ReadToEnd();
            process.WaitForExit();

            // 处理执行错误
            if (process.ExitCode != 0)
            {
                Console.WriteLine("Python脚本执行失败:");
                Console.WriteLine(error);
                return;
            }

            // 解析返回结果
            var result = JsonConvert.DeserializeObject<McLpResult>(output);
            Console.WriteLine("选中的点索引:");
            foreach (int idx in result.Selected) Console.WriteLine(idx);
            Console.WriteLine("\n覆盖的点索引:");
            foreach (int idx in result.Covered) Console.WriteLine(idx);
        }
    }
}

// 定义结果接收类
public class McLpResult
{
    public List<int> Selected { get; set; }
    public List<int> Covered { get; set; }
}

关键注意事项

  • Python环境配置:确保Python已安装numpy、gurobipy,且C#进程能找到python.exe(建议使用绝对路径避免环境变量问题)。
  • 大数组处理:若points数组过大,命令行参数会触发长度限制,此时改为标准输入传递:Python端从sys.stdin.read()读取JSON,C#端通过process.StandardInput.WriteLine(pointsJson)发送。
  • 调试技巧:捕获Python的标准错误输出,可快速定位脚本执行中的异常(如依赖缺失、参数解析错误)。

内容的提问来源于stack exchange,提问作者user2356725

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:25:03