का उपयोग कर फोरट्रान डीएलएल को स्ट्रिंग पास करना मैं पाइथन 2.7 में डीटीएल लोड करने की कोशिश कर रहा हूं। डीएलएल फोरट्रान का उपयोग करके लिखा गया था और इसमें कई सबराउटिन हैं। मैं सफलतापूर्वक निर्यात किए गए कार्यों में से कुछ को स्थापित करने में सक्षम था कि long
और double
पॉइंटर्स तर्क के रूप में।सीटीपीएस और पायथन
import ctypes as C
import numpy as np
dll = C.windll.LoadLibrary('C:\\Temp\\program.dll')
_cp_from_t = getattr(dll, "CP_FROM_T")
_cp_from_t.restype = C.c_double
_cp_from_t.argtypes = [C.POINTER(C.c_longdouble),
np.ctypeslib.ndpointer(C.c_longdouble)]
# Mixture Rgas function
_mix_r = getattr(dll, "MIX_R")
_mix_r.restype = C.c_double
_mix_r.argtypes = [np.ctypeslib.ndpointer(dtype=C.c_longdouble)]
def cp_from_t(composition, temp):
""" Calculates Cp in BTU/lb/R given a fuel composition and temperature.
:param composition: numpy array containing fuel composition
:param temp: temperature of fuel
:return: Cp
:rtype : float
"""
return _cp_from_t(C.byref(C.c_double(temp)), composition)
def mix_r(composition):
"""Return the gas constant for a given composition.
:rtype : float
:param composition: numpy array containing fuel composition
"""
return _mix_r(composition)
# At this point, I can just pass a numpy array as the composition and I can get the
# calculated values without a problem
comps = np.array([0, 0, 12.0, 23.0, 33.0, 10, 5.0])
temp = 900.0
cp = cp_from_t(comps, temp)
rgas = mix_r(comps)
अभी तक, बहुत अच्छा है।
समस्या पैदा होती है जब मैं एक और सबरूटीन जो इनपुट के रूप में कुछ तार की जरूरत है Function2
कहा जाता है की कोशिश करो। तार सभी निश्चित लंबाई (255) हैं और वे प्रत्येक स्ट्रिंग पैरामीटर की लंबाई के लिए भी पूछते हैं।
समारोह फोरट्रान में कार्यान्वित किया जाता है इस प्रकार है:
Subroutine FUNCTION2(localBasePath,localTempPath,InputFileName,Model,DataArray,ErrCode)
!DEC$ ATTRIBUTES STDCALL,REFERENCE, ALIAS:'FUNCTION2',DLLEXPORT :: FUNCTION2
Implicit None
Character *255 localBasePath,localTempPath,InputFileName
Integer *4 Model(20), ErrCode(20)
Real *8 DataArray(900)
अजगर में समारोह प्रोटोटाइप की स्थापना की है के रूप में
function2 = getattr(dll, 'FUNCTION2')
function2.argtypes = [C.POINTER(C.c_char_p), C.c_long,
C.POINTER(C.c_char_p), C.c_long,
C.POINTER(C.c_char_p), C.c_long,
np.ctypeslib.ndpointer(C.c_long , flags='F_CONTIGUOUS'),
np.ctypeslib.ndpointer(C.c_double, flags='F_CONTIGUOUS'),
np.ctypeslib.ndpointer(C.c_long, flags='F_CONTIGUOUS')]
इस प्रकार है और मैं का उपयोग कर इसे कहते:
base_path = "D:\\Users\\xxxxxxx\\Documents\\xxxxx\\".ljust(255)
temp_path = "D:\\Users\\xxxxxxx\\Documents\\xxxxx\\temp".ljust(255)
inp_file = "inp.txt".ljust(255)
function2(C.byref(C.c_char_p(base_path)),
C.c_long(len(base_path)),
C.byref(C.c_char_p(temp_dir)),
C.c_long(len(temp_dir))),
C.byref(C.c_char_p(inp_file)),
C.c_long(len(inp_file)),
model_array,
data_array,
error_array)
तार अनिवार्य रूप से पथ हैं। फ़ंक्शन Function2
पथ को पहचानता नहीं है और अंत में कुछ गैर-पठनीय पात्रों के साथ एक त्रुटि संदेश साबित करता है, जैसे:
forrtl: severe (43): file name specification error, unit 16, D:\Users\xxxxxxx\Documents\xxxxx\ωa
।
मैं जो समारोह प्राप्त करना चाहता था वह D:\Users\xxxxxxx\Documents\xxxxx\
था। जाहिर है, तार सही ढंग से पारित नहीं होते हैं।
मैंने पढ़ा है कि पायथन NULL
समाप्त तारों का उपयोग करता है। फोर्ट्रान डीएलएल के तारों को पार करते समय क्या यह समस्या हो सकती है? यदि हां, तो मैं इसके आसपास कैसे हो सकता हूं?
कोई सिफारिशें?
ठीक है। मूल्य से गुजरने के लिए 'argtypes' को बदल देगा। पिछली टिप्पणी के लिए, आप सही हैं। यह प्रोटोटाइप समारोह होना चाहिए था। ऊपर परिवर्तन किया है। कुछ कोड को सरल बनाना था क्योंकि इसे मूल रूप से कक्षा के रूप में लागू किया गया था। – d0m1n0
@eryksun ने मदद की। अब तारों को correclty पारित किया जा रहा है। डीएलएल को अभी भी 'फंक्शन 2' के साथ परेशानी है। इसके लिए अपने लेखकों के साथ काम करना होगा। – d0m1n0