在python中使用ctypes来访问C#dll的方法 [英] Using ctypes in python to acces a C# dll's methods

查看:148
本文介绍了在python中使用ctypes来访问C#dll的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的python程序的关键部分实现C#代码,使其更快。它说(在Python文档和本网站),您可以如下加载动态链接库(也就是说PyDocs):



cdll .LoadLibrary(your-dll-goes-here.dll)



这是我的代码中处理此功能的部分:

  ctypes import * 
z = [0.0,0.0]
c = [LEFT + x *( RIGHT-LEFT)/self.size,UP + y *(DOWN-UP)/self.size]
M = 2.0

iterator = cdll.LoadLibrary(RECERCATOOLS.dll)

array_result = iterator.Program.ITERATE(z [0],z [1],c [0],c [1],self.iterations,M)

z = complex(array_result [0],array_result [1])$ ​​b $ bc = complex(array_result [2],array_result [3])
last_iteration = int(round(array_result [4]))
我使用的RECERCATOOLS.dll是这样的(C#代码,不是C或C ++):



< b
$ b

 使用系统; 
使用System.Collections.Generic;
使用System.Linq;
使用System.Text;
使用KarlsTools;

public class Program
{
public static Array ITERATE(double z_r,double z_i,double c_r,
double c_i,int iterations,
double limit )
{
Complex z = new Complex(z_r,z_i);
Complex c = new Complex(c_r,c_i);

for(double i = 1; Math.Round(i)< = iterations; i ++)
{
z = Complex.Pow(z,2)+ c;
if(Complex.Abs(z)< limit)
{
double [] numbers = new double [] {Complex.Real(z),
Complex.Imag z),
Complex.Real(c),
Complex.Imag(c),
i};
返回数字;
}
}
double iter = iterations;
double [] result = new double [] {Complex.Real(z),
Complex.Imag(z),
Complex.Real(c),
Complex.Imag (c),
iter};
返回结果;
}
}

要构建此DLL,我使用Build命令Visual Studio 2010项目仅包含此文件,并引用Karlstools,这是允许我使用复数的模块。



我不知道为什么但是当我尝试运行我的Python代码时,它只会抛出一个异常:

  [...] 
array_result = iterator.Program.ITERATE(z [0],z [1],c [0],c [1],self.iterations,M)
文件C:\Python32\lib\ctypes \__init __。py,第353行,__getattr__
func = self .__ getitem __(name)
文件C:\Python32\lib\ctypes\__init __。py,第358行,__getitem__
func = self._FuncPtr((name_or_ordinal,self))
AttributeError:function'Program'not found

我需要帮助,因为即使将所有内容设置为 public ,并且函数为 static 或者eve n如果我尝试直接访问函数,而不指定程序类...我不知道问题可能在哪里。

解决方案

使用ctypes从Python中调用DLL的提示大部分时间都是以C或C ++而不是C#编写的DLL。使用C#,您可以使用CLR的整个机械设备,而且符号很可能会被破坏,而不是Ctypes所期望的,您将从您的输出阵列的垃圾回收中获得各种各样的麻烦。



通过使用python for dot net连接python和C#代码,我取得了非常好的成功( http://pythonnet.sf.net ),你可能想尝试一下。



另一方面,如果您使用纯粹的性能,请考虑使用Python / C API将代码重写为Python的本机C扩展( http://docs.python.org/c-api/ )。


I would like to implement C# code in a critical part of my python program to make it faster. It says (on Python documentation and this site) that you can load a Dynamic Link Library (and so say the PyDocs) as follows:

cdll.LoadLibrary("your-dll-goes-here.dll")

This is the part of my code that takes care of this feature:

from ctypes import *
z = [0.0,0.0]
c = [LEFT+x*(RIGHT-LEFT)/self.size, UP+y*(DOWN-UP)/self.size]
M = 2.0

iterator = cdll.LoadLibrary("RECERCATOOLS.dll")

array_result = iterator.Program.ITERATE(z[0],z[1],c[0],c[1],self.iterations,M)

z = complex(array_result[0],array_result[1])
c = complex(array_result[2],array_result[3])
last_iteration = int(round(array_result[4]))

And the RECERCATOOLS.dll that I use is this (C# code, not C or C++):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KarlsTools;

public class Program
{
    public static Array ITERATE(double z_r,double z_i,double c_r,
                        double c_i, int iterations, 
                        double limit)
    {
        Complex z = new Complex(z_r, z_i);
        Complex c = new Complex(c_r, c_i);

        for (double i = 1; Math.Round(i) <= iterations; i++)
        {
            z = Complex.Pow(z, 2) + c;
            if (Complex.Abs(z) < limit)
            {
                double[] numbers = new double[] { Complex.Real(z),
                                                  Complex.Imag(z),
                                                  Complex.Real(c),
                                                  Complex.Imag(c),
                                                  i};
                return numbers;
            }
        }
        double iter = iterations;
        double[] result = new double[]        { Complex.Real(z),
                                                  Complex.Imag(z),
                                                  Complex.Real(c),
                                                  Complex.Imag(c),
                                                  iter};
        return result;
    }
}

To build this DLL I use "Build" command over the Visual Studio 2010 project, which only contains this file and a reference to "Karlstools", a module that allows me to use complex numbers.

I don't know why but when I try to run my Python code, it just throws an exception:

    [...]
    array_result = iterator.Program.ITERATE(z[0],z[1],c[0],c[1],self.iterations,M)
  File "C:\Python32\lib\ctypes\__init__.py", line 353, in __getattr__
    func = self.__getitem__(name)
  File "C:\Python32\lib\ctypes\__init__.py", line 358, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'Program' not found

I need help with this, since it keeps throwing me exceptions even with everything is set to public and the function as static, or even when if I try to access the function directly without specifying the "Program" class... I have no clue where the problem could be.

解决方案

The tips you'll find regarding calling DLL from Python using ctypes rely most of the time to the DLL being written in C or C++, not C#. With C# you pull in the whole machinery of the CLR, and the symbols are most likely mangled and not what ctypes expect, and you'll get all sorts of troubles from the garbage collection of your output array.

I've had very good success when interfacing python and C# code by using python for dot net (http://pythonnet.sf.net), you may want to try this.

On the other hand if you are in for pure performance, consider rewriting your code as a native C extension for Python using the Python/C API (http://docs.python.org/c-api/).

这篇关于在python中使用ctypes来访问C#dll的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆