
在现代软件开发中,跨语言调用是一项十分常见的需求。比如题主需求提到的把 Python 应用打包成 dll,供 C# 程序调用。
Python 提供了多个模块和工具支持与其他语言的交互。利用 ctypes 或 cffi 模块,以及 pybind11,我们可以将 Python 函数封装为 C 接口。同时,借助 pyinstaller 等工具,我们可以将 Python 程序打包为独立运行的二进制文件。
ctypes 和 cffi:提供了与 C 接口的交互能力。pyinstaller:用于将 Python 程序打包为二进制格式。DllImport:在 C# 中加载并调用外部 DLL。我们动手逐一实现上面三种方案。
以下是一个示例 Python 脚本,定义了一个简单的数学运算函数。
def add(a, b):
"""
Returns the sum of two numbers.
"""
return a + b
if __name__ == "__main__":
import ctypes
from ctypes import CFUNCTYPE, c_int
# Define the function signature for the C interface
AddFunc = CFUNCTYPE(c_int, c_int, c_int)
# Create an instance of the function
add_c = AddFunc(add)
# Export the function for C#
ctypes.pythonapi.Py_Initialize()
ctypes.CDLL(None).add = add_cctypes 生成 DLL将 Python 脚本打包为 DLL 文件。
使用 pyinstaller 工具:
pyinstaller --onefile --name=my_library --dll my_script.py此命令会生成一个名为 my_library.dll 的文件。
确认 dist/ 目录下生成的 DLL 文件包含所有所需的功能。
以下是 C# 的代码示例,演示如何调用生成的 DLL。
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("my_library.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int add(int a, int b);
static void Main(string[] args)
{
int result = add(3, 5);
Console.WriteLine("Result: " + result);
}
}my_library.dll 放置在 C# 项目的可执行文件目录中。Result: 8,则说明调用成功。在 Python 中,我们通过 ctypes 模块的 CFUNCTYPE 方法,将 Python 函数转换为 C 语言的函数指针,从而使其能够被其他语言调用。
AddFunc = CFUNCTYPE(c_int, c_int, c_int)
add_c = AddFunc(add)这种转换的关键在于函数签名的定义。我们需要确保参数类型和返回值类型与 C 的标准一致。
在 C# 中调用 DLL 时,必须指定调用约定(CallingConvention)。Python 打包生成的 DLL 默认使用 Cdecl 调用约定。
[DllImport("my_library.dll", CallingConvention = CallingConvention.Cdecl)]如果调用约定不匹配,将导致运行时错误。
Python 打包生成的 DLL 文件可能包含整个 Python 运行时,这会导致体积较大。可以通过以下方式优化:
--exclude-module 参数排除不必要的模块。UPX 压缩工具进一步压缩生成的 DLL。在调试过程中,可以通过以下方式排查问题:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。