简体   繁体   English

使用 Python 中 C DLL 中的函数时出现奇怪的情况

[英]Strange Occurance when using functions from C DLL in Python

I'm having a strange issue where I'm using DLL functions that return more or less the same float value (ie their residual is less than 1e-08), but I'm somehow seeing different behavior.我有一个奇怪的问题,我正在使用 DLL 函数返回或多或少相同的浮点值(即它们的残差小于 1e-08),但我不知何故看到了不同的行为。

Here is the general way I'm writing the function prototypes in Python;这是我在 Python 中编写 function 原型的一般方式; this should be enough information to give you an idea of how I'm doing this part.这应该足以让您了解我是如何做这部分的。

class OWTP:

    def __init__(self):
        self._lib = CDLL("../Include/OWTP.dll")
        protoTwoParams = CFUNCTYPE(c_double, c_double, c_double)
        ptApi = (1, "P"), (1, "T")

        #properties as functions of pressure and temperature
        self.v_PT = protoTwoParams(("v_P_T", self._lib), ptApi)
        self.u_PT = protoTwoParams(("u_P_T", self._lib), ptApi)
        self.s_PT = protoTwoParams(("s_P_T", self._lib), ptApi)
        self.h_PT = protoTwoParams(("h_P_T", self._lib), ptApi)
        self.cp_PT = protoTwoParams(("cp_P_T", self._lib), ptApi)
        self.cv_PT = protoTwoParams(("cv_P_T", self._lib), ptApi)
        #much more past this point, but it's generally more of the same

Next, I'm writing a couple of classes that are intended to basically do a bunch of calculations and hold a bunch of property data.接下来,我正在编写几个类,它们基本上是为了进行一堆计算并保存一堆属性数据。

Root class根class

class ThermoProperties(ABC):

    def __init__(self):
        self._P = float('nan')
        self._T = float('nan')
        self._h = float('nan')
        self._s = float('nan')
        self._u = float('nan')
        self._v = float('nan')
        self._cp = float('nan')
        self._cv = float('nan')

Concrete class混凝土 class

class OrdinaryWaterThermoProperties(ThermoProperties):

    _owtp = OWTP()

    def __init__(self):
        super(ThermoProperties, self).__init__()
        self._x = float('nan')

And now for the function in question that's on OrdinaryWaterThermoProperties现在对于在OrdinaryWaterThermoProperties上有问题的 function

def Set_Tx(self, T, x):
    P = self._owtp.PSat_T(T)
    self._P = P
    self._T = T
    self._v = self._owtp.v_Tx(T,x)
    self._u = self._owtp.u_Tx(T,x)
    self._s = self._owtp.s_Tx(T,x)
    self._h = self._owtp.h_Tx(T,x)
    self._x = x

    #at this point, linearly interpolate between the cps
    #and cvs @ 0 and 1 vapor quality

    if (x <= 1e-08):
        cpLow = self._owtp.cp_Ps(P, self._s)
        cvLow = self._owtp.cv_Ps(P, self._s)
    else:
        s = self._owtp.s_Tx(T,0)
        cpLow = self._owtp.cp_Ps(P, s)
        cvLow = self._owtp.cv_Ps(P, s)

    if (1.0 - x <= 1e-08):
        cpHigh = self._owtp.cp_Ps(P, self._s)
        cvHigh = self._owtp.cv_Ps(P, self._s)
    else:
        s = self._owtp.s_Tx(T,1)
        cpHigh = self._owtp.cp_Ps(P, s)
        cvHigh = self._owtp.cv_Ps(P, s)

    self._cp = cpLow + x * (cpHigh - cpLow)
    self._cv = cvLow + x * (cvHigh - cvLow)

The issue is that the last 2 lines evaluate to some ridiculous number.问题是最后两行评估为一些荒谬的数字。 At first, I obviously thought that this was just an issue with the library that I wrote, but as I tried more things, I'm not so sure about that now.起初,我显然认为这只是我编写的库的问题,但是当我尝试更多的东西时,我现在不太确定了。

This line self._s = self._owtp.s_Tx(T,x) stores a nearly identical value (ie residual less than 1e-08) if I replace it with this self._s = self._owtp.s_Px(P,x) , but once I do the replacement, those last 2 lines evaluate to the reference values I have.如果我用这个self._s = self._owtp.s_Px(P,x)替换这条线self._s = self._owtp.s_Tx(T,x) x) ,但是一旦我进行替换,最后两行将评估为我拥有的参考值。

Is there something I've done wrong or is there something that Python does to which I'm not aware?是我做错了什么还是 Python 做了什么我不知道的事情?

I just want to know why exactly this is happening.我只是想知道为什么会发生这种情况。

Please let me know if more info is needed.如果需要更多信息,请告诉我。

Edit:编辑:

Using these commands:使用这些命令:

from properties import *
p = OrdinaryWaterThermoProperties()
p.Set_Tx(507.008845,1)

#a function that does the same thing as p.Set_Tx(), but uses a different input.
p.Set_Px(3.000021637933144,1)

I generated these outputs:我生成了这些输出:

After using p.Set_Tx(507.008845,1) :使用p.Set_Tx(507.008845,1)后:

cpLow = 4.713721716228506
cvLow = 3.1991548400342227
cpHigh = -892771.9785675189
cvHigh = -892771.9785675189
self._s = 6.185784988287523
self._cp = -892771.9785675189
self._cv = -892771.9785675189
P = 3.000021637933144
T = 507.008845

After using p.Set_Px(3.000021637933144,1) :使用p.Set_Px(3.000021637933144,1)后:

cpLow = 4.713721716228509
cvLow = 3.1991548400342205
cpHigh = 3.612225802173107
cvHigh = 2.328260186952078
self._s = 6.185784988287527
self._cp = 3.612225802173107
self._cv = 2.328260186952078
P = 3.000021637933144
T = 507.0088450000006

Note, that p.Set_Px(3.000021637933144,1) produces the desired outputs of self._cp and self._cv .请注意, p.Set_Px(3.000021637933144,1)会产生self._cpself._cv的所需输出。

After further investigation, it seems that there was a very small floating point error band (less than 1e-10) where self._s was effectively infeasible in the C DLL.经过进一步调查,似乎在self._s DLL 中 self._s 存在一个非常小的浮点误差带(小于 1e-10)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从Cython C调用python函数时的奇怪行为 - Strange behaviour when calling python functions from cython c 当dll具有嵌入式Python解释器时,将函数从dll(用C ++编程)导入Python脚本 - Import functions from dll (programmed in C++) into Python script when the dll has an embedded Python interpreter 从 Python 调用时 C DLL 破解 - C DLL crack when called from Python 使用库函数时,Python ctypes dll调用访问冲突 - Python ctypes dll call access violation when using library functions 谁能解释这种奇怪的python乌龟的发生? - Can anyone explain this strange python turtle occurance? 使用ctypes将文档字符串添加到从dll提取的python函数中 - Adding docstrings to python functions pulled from dll using ctypes 如何从python访问C ++ dll中的函数,我只有一个包(标头文件和dll文件) - How to access functions in a C++ dll from python ,all I have is a package(a header file and a dll file) WindowsError:异常:使用从C ++到Python的ctypes创建DLL时发生访问冲突或Windows错误193 - WindowsError: exception: access violation or Windows Error 193 when creating a DLL using ctypes from C++ to Python 使用 Python C API 时的奇怪内存行为 - Strange memory behaviour when using Python C API 使用外部C DLL时Python中的内存泄漏 - Memory leaks in Python when using an external C DLL
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM