CSharp调用python
Why
- 因为公司最近有这一部分的需求,所以我这边挺感兴趣也就打算看一看。其实总结来说使用
C#
调用Python
是一件非常简单的事情,因为python
本身就是跨平台的,所以其实直接在调用处配置一份python
的环境不就可以了,然后C#
开个进程直接调用环境的python.exe
来执行某个py
文件不就行了呗。不要跟我扯什么一些包例如ironpython
啊啥的,那玩意儿根本就不稳定,我之前试的就是各种配置杂乱然后还是要安装包,没啥区别的好吧。
How
- 因为后续会使用
C++
来调用C#
,所以这里需要建立C#
的类库项目。代码如下:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LaserLib
{
public class PQLib
{
public string Start(string dt1, string dt2)
{
var pyPath = $@"{AppDomain.CurrentDomain.BaseDirectory}dllpython.py";
var pyExe = $@"{AppDomain.CurrentDomain.BaseDirectory}Python37\python.exe";
var process = new ProcessStartInfo()
{
FileName = pyExe,
Arguments = $"{pyPath} {dt1} {dt2}",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
};
var msg = string.Empty;
using (var proc = Process.Start(process))
{
proc?.WaitForExit();
var output = proc?.StandardOutput.ReadToEnd();
var error = proc?.StandardError.ReadToEnd();
msg = string.IsNullOrWhiteSpace(output) ? error : output;
}
return msg;
}
}
}
- 同时给大家看看我的项目下的样式。

- 可以看到是直接把完整的
python
环境拿到生成目录下的,当然这个只是生成类库,所以没有exe
。请看下方继续使用C++
调用C#
的方法。
- 注意当前项目生成一定要切换成
x64
的,后续才能成功。
C++调用CSharp
- 以下简单说一下如何使用
C++
调用CSharp
的上述生成的类库。
How
- 你需要新建一个有关于
C++
的win32
的空项目,然后点击这个项目设置属性。属性->配置属性->高级->公共语言运行时配置为clr
,请注意这是必须的同时也是很重要的。

- 然后添加一个
cpp
文件,同时在里面书写如下代码。
using namespace std;
#include <iostream>
#include <tchar.h>
#include <msclr/marshal.h>
#include <msclr/marshal_cppstd.h>
#using "C:\Users\10335\Desktop\peng\work\demo\CSharpToPython\src\LaserLib\bin\Debug\LaserLib.dll"
using namespace System;
using namespace msclr::interop;
int _tmain(int argc, _TCHAR* argv[])
{
LaserLib::PQLib^ pq = gcnew LaserLib::PQLib();
System::String^ dt1 = "效率优先";
System::String^ dt2 = "2";
auto msg = pq->Start(dt1, dt2);
string result = marshal_as<std::string>(msg);
std::cout << result << endl;
return 0;
}
- 同时你也需要将上述的
python
环境和需要的py
文件复制到生成的目录下,如果不出意外的话你这个时候就会出出现你想要的结果了。
Tips
- 使用上述方式在三方之间调用的时候需要注意的是,你所使用的
py
文件中如果涉及到文件的操作,例如打开当前目录下的某个文件,别人可能是偷懒直接使用joblib.load(f'OneHot_model.pkl')
,这种方式使用python
执行时没问题的,但是一旦三者串联起来就会显示找不到文件了,所以正确的写法应该如下:
curDir = sys.path[0]
d1 = joblib.load(f'{curDir}\\OneHot_model.pkl')
- 注意程序中的文件路径中一定不要出现空格,例如
a b
这种,不然无法找到python.exe
。
- 三方调用基本是可以打通的,而且其实都不是很难,没有特别多的操作,只不过很多地方需要细心一点就行了。
Ok,Have Fun!