回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我想通过使用ctypes在一些Python代码中使用C库。
我的问题是我不懂C语言。我试着读代码和C结构已经好几天了,但我还是被一个问题困住了。我对Python也相当陌生,因为我目前正在从Matlab进行转换,因此我的Python仅限于科学的Python应用程序。这个问题非常具体,但我认为解决方案是一般C库/Python链接感兴趣的。在</p>
<p>我用的是一个叫做Iphreeqc的地球化学模型`http://wwwbrr.cr.usgs.gov/projects/GWC_coupled/phreeqc/index.html(iphreeqc-2.18.0-5314。焦油gz,从OS X 10.6上的源代码编译。超链接不工作,因为SO垃圾邮件预防)。我想从C库的计算中提取值到Python中。在</p>
<p><strong>我怀疑我在Python代码的结构和联合部分中出错了</strong>,但我似乎无法找出原因。在</p>
<p>Python代码:</p>
<pre><code>import ctypes
iphreeqc = ctypes.CDLL("libiphreeqc.0.dylib", ctypes.RTLD_GLOBAL)
# C structures from var.h
class VAR_TYPE(ctypes.Structure):
_fields_ = [
("TT_EMPTY",ctypes.c_int),
("TT_ERROR",ctypes.c_int),
("TT_LONG",ctypes.c_int),
("TT_DOUBLE",ctypes.c_int),
("TT_STRING",ctypes.c_int)]
(TT_EMPTY,
TT_ERROR,
TT_LONG,
TT_DOUBLE,
TT_STRING)=map(ctypes.c_int, xrange(5))
class VRESULT(ctypes.Structure):
_fields_ = [
("VR_OK",ctypes.c_int),
("VR_OUTOFMEMORY",ctypes.c_int),
("VR_BADVARTYPE",ctypes.c_int),
("VR_INVALIDARG",ctypes.c_int),
("VR_INVALIDROW",ctypes.c_int),
("VR_INVALIDCOL",ctypes.c_int)]
(VR_OK,
VR_OUTOFMEMORY,
VR_BADVARTYPE,
VR_INVALIDARG,
VR_INVALIDROW,
VR_INVALIDCOL)=map(ctypes.c_int, xrange(0,-6,-1))
class _U(ctypes.Union):
_fields_ = [("lVal", ctypes.c_long),
("dVal", ctypes.c_double),
("sVal", ctypes.c_char),
("vresult", VRESULT)]
class VAR(ctypes.Structure):
_anonymous_ = ("pvar",)
_fields_ = [
("pvar", _U),
("type", VAR_TYPE)]
# Run model
Id=iphreeqc.CreateIPhreeqc()
dbloade = iphreeqc.LoadDatabase(Id,"phreeqc.dat")
estring=iphreeqc.OutputErrorString(Id)
# Model input
iphreeqc.AccumulateLine(Id,"TITLE Example 2.--Temperature dependence of solubility")
iphreeqc.AccumulateLine(Id," of gypsum and anhydrite ")
iphreeqc.AccumulateLine(Id,"SOLUTION 1 Pure water ")
iphreeqc.AccumulateLine(Id," pH 7.0 ")
iphreeqc.AccumulateLine(Id," temp 25.0 ")
iphreeqc.AccumulateLine(Id,"EQUILIBRIUM_PHASES 1 ")
iphreeqc.AccumulateLine(Id," Gypsum 0.0 1.0 ")
iphreeqc.AccumulateLine(Id," Anhydrite 0.0 1.0 ")
iphreeqc.AccumulateLine(Id,"REACTION_TEMPERATURE 1 ")
iphreeqc.AccumulateLine(Id," 25.0 75.0 in 50 steps ")
iphreeqc.AccumulateLine(Id,"SELECTED_OUTPUT ")
iphreeqc.AccumulateLine(Id," -file ex2.sel ")
iphreeqc.AccumulateLine(Id," -user_punch true ")
iphreeqc.AccumulateLine(Id," -reset false ")
iphreeqc.AccumulateLine(Id," -simulation false ")
iphreeqc.AccumulateLine(Id," -selected_out true ")
iphreeqc.AccumulateLine(Id," USER_PUNCH ")
iphreeqc.AccumulateLine(Id," -start ")
iphreeqc.AccumulateLine(Id," 10 punch - LA('H+') ")
iphreeqc.AccumulateLine(Id," -end ")
iphreeqc.AccumulateLine(Id,"END ")
# run model
runout=iphreeqc.RunAccumulated(Id)
estring2=iphreeqc.OutputErrorString(Id)
a=iphreeqc.GetSelectedOutputRowCount(Id)
b=iphreeqc.GetSelectedOutputColumnCount(Id)
print a
print b # this works, gives correct number of rows and columns
vart=VAR()
iphreeqc.VarInit(ctypes.byref(vart))
c=iphreeqc.GetSelectedOutputValue(Id, 43, 0, ctypes.byref(vart)) #tries to extract value from row 43, column 1
print c # c is here VRESULT. this works properly giving the right error number (0 to -6). Gives 0 in this case which is VR_OK
</code></pre>
<p>所选行、列中的值是double,但我也尝试过使用字符串值和long(整型)值,但没有成功。
我希望如此变量dVal(对于string或long,则为.sVal或lVal)以包含我想要的值,但它不是。
我也希望VAR_TYPE的TT_u字段中有一个是1,但它们都是0。
似乎.dVal、.sVal和.lVal实际上包含VAR_类型号(介于0和4之间),并且正确地报告了这一点(即3表示double类型,2表示long类型)。在</p>
<p><strong>我的问题是:如何修复代码,使VAR_TYPE字段反映变量类型,而变量类型现在在.lVal字段中返回。
我怎样才能得到我想提取的正确值变量x值领域?在Python结构/联合代码中是否缺少一些指针?</strong></p>
<p>结构和联合来自的C源(Var.h):</p>
<p><a href="http://wwwbrr.cr.usgs.gov/projects/GWC_coupled/iphreeqc/Var_8h_source.html" rel="nofollow">http://wwwbrr.cr.usgs.gov/projects/GWC_coupled/iphreeqc/Var_8h_source.html</a></p>
<p>我试图在Python中重现的C示例(v是Python代码中的变量'vart',我暂时忽略循环等):</p>
^{pr2}$
<p>C示例取自:(向下滚动一点)
<a href="http://wwwbrr.cr.usgs.gov/projects/GWC_coupled/iphreeqc/IPhreeqc_8h.html#a9f0ffd11e25a7e8f05d800623b14acf5" rel="nofollow">http://wwwbrr.cr.usgs.gov/projects/GWC_coupled/iphreeqc/IPhreeqc_8h.html#a9f0ffd11e25a7e8f05d800623b14acf5</a></p>
<p>我在OSX10.6.6上使用的是cTypes1.1.0和Python2.6.6</p>
<p>很抱歉这个问题太长了,希望一些聪明人能帮我解决问题,或者给我指出正确的方向。在</p>
<p>非常感谢</p>