Python 调用 C# 动态链接库(数组类型传值)

基于.NET 7 的 AOT 功能加持,C# 可以将程序进行AOT编译,变成纯机器码文件。因此C# 通过AOT 编译的dll 不用依赖运行时,可以被其他语言编写的程序调用。

详细的.NET 7 AOT 生成dll的入门教程可以参考这篇文章 (文章作者 InCerry)

跨语言调用C#代码的新方式-DllExport - InCerry - 博客园 (cnblogs.com)

上述文章中介绍了如何发布dll,传递数值类型,字符串类型的参数,本篇主要讲解如何传递数组类型的参数。

数组类型 属于引用类型,我们并不能在传参时,直接将整个数组丢过去,而是要传递数组的地址(指针)以及数组的长度大小,因此在定义函数形参时,定义一个IntPtr 地址指针 ,一个int 数组大小

using System.Runtime.InteropServices;

namespace testdll
{
    public class Class1
    {
        //声明这是一个仅非托管类型的导出函数
        [UnmanagedCallersOnly(EntryPoint = "double_array")]
        public static IntPtr double_array(IntPtr array_ptr, int len)
        {
            // 将指针转换成 double 数组
            double[] result = new double[len];
            Marshal.Copy(array_ptr, result, 0, len);

            // 将数组的每个元素都加一
            for(int i = 0; i < len; i++)
            {
                result[i]++;
            }

            // 将 double 数组转换为指针
            IntPtr arrayPointer = Marshal.AllocHGlobal(sizeof(double) * len);
            Marshal.Copy(result, 0, arrayPointer, len);

            return arrayPointer;
        }
    }
}

如果你对上述代码有不理解地方,可以将其复制到CHATGPT中查看代码的详细含义,上述代码也是我慢慢引导chatGPT写出的代码,最终解释权归chatGPT所有(手动狗头

编译之后得到dll文件,放到你的py项目文件夹中,编写python代码:

import ctypes


l1=[2,3,4,5,6.1]
# 加载DLL库
mydll = ctypes.cdll.LoadLibrary("./testdll.dll")

# 定义函数的输入参数和返回值类型
mydll.double_array.restype = ctypes.POINTER(ctypes.c_double)

# 创建一个double数组
input_array = (ctypes.c_double * len(l1))(*l1)

# 调用函数并获取返回结果
result_array_ptr = mydll.double_array(input_array, len(l1))

# 将返回的数组转换为列表
result_list = [result_array_ptr[i] for i in range(len(l1))]

# 打印结果
print(result_list)

同样的该代码的解释权归chatGPT所有

闲话时间:

如果你看到了这里,我希望你继续往下读一下我的废话,

思考一下,你为什么想用python调用动态链接库?能不能采用纯python手段?

其实这东西应用场景不是很多,如果考虑性能的话,完全可以使用numpy进行计算,如果是循环和判断影响了你代码性能,调用dll也不是特别好的方案,因为,上述代码中你也看到了,c数组指针完全就是一个中间数据类型,我们传入数据还是使用返回结果,都转成自己语言的数据类型,数据类型转换也增加了成本,而且我的代码中还涉及到了内存数据复制(python将数组传入c#dll,代码第一行进行的数据复制操作),因为你不能直接操作python数据,这很危险。

Python 调用 外部 dll 可能的应用场景是:

1.你的主要编程语言不是python

2.不想用Python 三方库来做,打包出来的程序太大

3.Python 中没有特别好的你想要的三方库,或学习成本高,恰巧你又掌握了别的语言对应的功能库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值