首页 > 编程语言 >Python中动态调用C#的dll动态链接库中方法

Python中动态调用C#的dll动态链接库中方法

时间:2024-05-25 14:58:59浏览次数:24  
标签:Python module dll C# 模块 import

在Python中调用C#的dll库_哔哩哔哩_bilibili 

环境准备: 

安装 pythonnet

pip install pythonnet

 在Python中调用C#动态链接库(DLL),可以使用pythonnet库,它允许直接使用 .NET 的程序集。以下是一个示例,展示如何使用pythonnet调用C#动态链接库中的方法。

【pythonnet详解】—— Python 和 .NET 互操作的库-CSDN博客

 注意事项

在pycharm中写import clr,若根据提示安装clr模块,在调用C#的dll动态连接库时会报错module 'clr' has no attribute 'AddReference' ·建议pip uninstall clr,安装pythonnet模块

module 'clr' has no attribute 'AddReference' · Issue #319 · r0x0r/pywebview · GitHub

C#中调用dll动态链接库

案例1:

在Python中调用C#的dll库_哔哩哔哩_bilibili

C# 代码

python 代码

 

案例2: 

C#代码

假设有一个C#动态链接库MyLibrary.dll,其中有一个类MyClass,包含一个方法MyMethod,该方法接收两个整数参数并返回它们的和。

// MyLibrary.cs
namespace MyLibrary
{
    public class MyClass
    {
        public int MyMethod(int a, int b)
        {
            return a + b;
        }
    }
}
Python代码 
import clr  # 导入pythonnet

# 添加DLL引用
clr.AddReference(r'C:\path\to\MyLibrary.dll')

# 导入命名空间
from MyLibrary import MyClass

# 创建类的实例
my_instance = MyClass()

# 调用方法
result = my_instance.MyMethod(3, 5)

print(f"The result is: {result}")

C#中动态调用dll动态链接库的方法 

需求:已知方法名称、参数个数和参数类型,在python中调用c#动态链接库

C#中与Python中类型的对应

在使用 pythonnet 调用 C# 动态链接库中的方法时,Python 和 C# 的参数类型需要相互对应。以下是常见的类型映射

 

  • 对于复杂对象,确保已导入相应的命名空间(如 System.Collections.Generic)。
  • 在 Python 中使用 List, Dictionary 等 C# 泛型类型时,需要指定类型参数。

案例1:

 C#代码

假设有一个C#动态链接库MyLibrary.dll,其中有一个类MyClass,包含一个方法MyMethod,该方法接收两个整数参数并返回它们的和。

// MyLibrary.cs
namespace MyLibrary
{
    public class MyClass
    {
        public int MyMethod(int a, int b)
        {
            return a + b;
        }
    }
}
Python代码 

核心:获取非静态方法

  • method = getattr(my_instance, method_name),利用getattr(par1,par2)方法

        //参数1为类的实例,参数2为方法名称

import clr
import System

# 添加DLL引用
clr.AddReference(r'C:\path\to\MyLibrary.dll')

# 导入命名空间
from MyLibrary import MyClass

# 创建类的实例
my_instance = MyClass()

# 动态调用方法
method_name = "MyMethod"
params = (3, 5)

# 获取方法
method = getattr(my_instance, method_name)

# 调用方法
result = method(*params)

print(f"The result is: {result}")

案例2:

 C#代码:

假设有一个C#动态链接库ClassLibrary1.dll,其中有一个类TestCsharp,包含一个静态方法方法test2()和一个非静态方法test1().

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public class TestCsharp
    {

        //private string name;
        //带参构造函数
        //public TestCsharp(string name) {
        //    this.name = name;
        //}
        // 无参构造函数
        public TestCsharp() { 
        }
        public int test1(int times) { 
            return times;
        }
        //静态方法
        public static int test2(int times) {
            Console.WriteLine(times);
            return times;
        }
        
    }
}
Python代码:

1.利用importlib和getattr()动态导入模块和类

  •     module_1 = importlib.import_module(namespace)//动态获取模块
  •     class_1 = getattr(module_1,  className)//动态获取类

2.利用getattr()方法动态获取静态方法和非静态方法

  •         method1 = getattr(my_instance,methodName1)//非静态方法
  •         method2 = getattr(class_1 ,methodName2)//静态方法
import os
import sys
import clr
import importlib


if __name__ == '__main__':
    dllName='ClassLibrary1.dll'
    namespace='ClassLibrary1'
    className='TestCsharp'
    methodName1='test1'
    methodName2 = 'test2'
    # paramsType=''
    paramsVal1=1
    paramsVal2 = 2

    #工作目录设置dll所在目录
    sys.path.append(os.getcwd())
    #找到c#程序集
    clr.FindAssembly(dllName)
    #设置命名空间参考【设置模块】
    dll=clr.AddReference(namespace)
    # print(dll)

    #从指定命名空间导入类
    # from ClassLibrary1 import TestCsharp

    module_1 = importlib.import_module(namespace)
    class_1 = getattr(module_1,  className)

    #实例化,非静态方法
    my_instance = class_1()
    # 获取方法
    method1 = getattr(my_instance,methodName1)
    #调用非静态方法
    print(method1(paramsVal1))

    method2 = getattr(class_1 ,methodName2)
    #调用静态方法
    print(method2(paramsVal2))

附加:

importlib

是 Python 标准库中的一个模块,用于动态导入模块。它提供了一系列函数和类,允许你在运行时加载和操作模块。以下是 importlib 的详细介绍,包括常见用法和示例。

基本概念

importlib 模块实现了 import 语句背后的导入机制。它提供了更为灵活和动态的方式来导入模块,允许你在运行时根据需要加载和操作模块,而不仅仅是在编译时或脚本开始时导入模块。

使用 importlib.import_module() 可以动态地导入模块

import importlib

# 导入一个模块
module_name = 'math'
math_module = importlib.import_module(module_name)

# 使用导入的模块
result = math_module.sqrt(16)
print(result)  # 输出: 4.0

importlib 是 Python 中强大且灵活的模块导入机制。它提供了动态导入、模块重载、自定义导入逻辑和其他高级功能,使得模块管理更加灵活和强大。通过理解和使用 importlib,你可以更好地控制 Python 程序中的模块导入和管理。

getattr

是 Python 的一个内置函数,用于从对象中获取属性值。它接受一个对象、属性名(字符串形式)和一个可选的默认值作为参数。如果指定的属性存在,则返回该属性的值;如果属性不存在且提供了默认值,则返回默认值;如果属性不存在且没有提供默认值,则引发 AttributeError 异常。

Python函数介绍:getattr函数的用法和示例-Python教程-PHP中文网

相关文章推荐:Java调用C++的DLL设计!!!解耦实用!!!-CSDN博客

标签:Python,module,dll,C#,模块,import
From: https://blog.csdn.net/m0_55049655/article/details/139176115

相关文章

  • CentOS7的操作——学会上分不是梦
     目录常用命令文件与目录操作查看文件内容文本内容处理查询操作压缩、解压yum安装器网络相关系统相关XSheel5相关操作窗体快捷键操作小技巧结束语这两天一直在对CentOS7.2进行初体验,各种学习命令肿么用,不过其实大多和DOS是一样的,只是命令的表达上可能有点......
  • wxPython==4.2.1 aui.AuiToolBar 如何去掉烦人的抓手?
    aui.AuiToolBar如何去掉烦人的抓手?最近在用wxPython做一些GUI小应用,发现工具栏总有几个点(抓手),很影响美观,如下:目前官方没有提供隐藏抓手的功能,需要更改源码的auibar.py文件注释掉对应代码。如下:#注释这句,大致在auibar.py+3480(不同版本可能有差异)#self._art.DrawGrip......
  • Qt - Qt6中QTextStream类的setCodec方法没有了,怎么解决写中文文本乱码
    简介场景:程序在linux下运行,将中英文写入文本,将文本在windows上打开时,中文出现乱码 原Qt5中:QFilefile;file.open(QIODevice::WriteOnly|QIODevice::Text);QTextStreamtextStream(&file);textStream.setCodec("GBK");使用 QTextStream类的 setCodec方法即可解决上......
  • C++ - 比较两个浮点数大小
    简介两个浮点数不能直接使用 ==来确定相等,因为浮点数精度可能导致微小的误差 方法一:使用std::abs()函数来比较两个浮点数的差值是否小于一个非常小的阈值floata=1.5;floatb=2.3;floatepsilon=1e-9;if(std::abs(a-b)<epsilon){cout<<"aiseq......
  • Linux命令探索:深入了解which命令
    Linux命令探索:深入了解which命令在Linux系统中,which命令是一个非常有用的工具,用于定位并显示给定命令的绝对路径。本文将详细介绍which命令的用法,帮助读者更好地理解和运用这个命令。了解which命令which命令用于查找并显示系统中某个命令的绝对路径。它的基本语法如下:which......
  • reactk中useCallback的使用场景
    useCallback 是React中的一个Hook,用于优化性能并避免不必要的函数重新创建。在React中,当一个组件重新渲染时,其内部的函数也会被重新创建。这可能会导致向子组件传递的回调函数发生变化,从而导致子组件不必要地重新渲染。为了避免这种情况,可以使用 useCallback 来创建记忆......
  • Linux cp命令参数和选项
    Linuxcp命令参数和选项在Linux系统中,cp命令是一个非常重要的命令,它用于复制文件和目录。在这篇博客中,我们将深入探讨cp命令的参数和选项,希望能帮助读者更好地理解和使用这个命令。1. cp命令的基本用法cp命令的基本用法非常简单,只需要在命令行中输入cp,然后跟上你想要复制的......
  • Spring的BeanFactoryPostProcessor和BeanPostProcessor区别?
    1、BeanFactoryPostProcessor是用于在容器实例化Bean之前对Bean的配置信息进行修改的接口,它允许对BeanFactory进行后处理,比如修改BeanDefinition的属性值等。BeanFactoryPostProcessor是在Bean的实例化之前执行的,对BeanFactory进行配置。2、BeanPostProcessor是用于在Bean实......
  • 带你实现TexturePacker中的网格打包功能
    现在手头上有一堆相同大小的图片,如下图所示:我想将它们打包进一张大图片中,主要是便于资源管理。本着能偷懒就偷懒的原则,看看市面上有没有类似功能的软件,果然,找到了一款名为TexturePacker的软件。但很可惜,这个功能是收费的。毕竟需求比较简单,还是自己动手,丰衣足食,试着用Python实现......
  • C++基础知识学习笔记(3)
    资料来源https://www.bilibili.com/video/BV1et411b73Z?p=84&vd_source=cc561849591f6a210152150b2493f6f3核心内容程序的内存模型代码区全局区在函数外面声明了全局变量,在main函数里面创建了局部变量,打印了其地址:静态变量:在普通变量前面加一个static,属于静态变量。静......