Найти - Пользователи
Полная версия: Вызов функции из dll
Начало » Python для новичков » Вызов функции из dll
1
streetmover
Доброго времени суток всем и с праздником.

Проблема при вызове функции из dll библиотеки, видимо что-то не так с типами передаваемых аргументов.

from ctypes import *
from array import array

swedll = windll.swedll32

#************************************************************
# вызов функции swedll.swe_julday() проходит нормально
#************************************************************
sName = ""
sName = swedll.swe_get_planet_name(1, sName)
jul_day_UT = 0
jul_day_UT = swedll.swe_julday(2011, 4, 23, c_double(0.10), 1)
print "jul_day_UT: ", jul_day_UT

#************************************************************
# вызов функции swe_calc_ut() не работает
#************************************************************
arr_lst = [30.0, 40.0, 0.0, 0.0, 0.0, 0.0 ]
arr_type = c_double * len(arr_lst)
arr = arr_type(*arr_lst)
sErr = create_string_buffer(256)

ret_flag = swedll.swe_calc_ut(c_int(jul_day_UT), c_int(1), c_int(0), byref(arr), byref(sErr))

print "ret_flag: ", ret_flag
for i in arr: print i

swedll.swe_close()
При попытке его выполнить выводится следующая ошибка:

Traceback (most recent call last):
File “…swefem.py”, line 19, in <module>
ret_flag = swedll.swe_calc_ut(c_int(jul_day_UT), c_int(1), c_int(0), byref(arr), byref(sErr))
ValueError: Procedure probably called with not enough arguments (4 bytes missing)


Описание функции кратко:
——————————————————————————————
int swe_calc_ut ( double tjd_ut, int ipl, int iflag, double* xx, char* serr),

where
tjd_ut =Julian day, Universal Time
ipl =body number
iflag =a 32 bit integer containing bit flags that indicate what kind of computation is wanted
xx =array of 6 doubles for:
longitude,
latitude,
distance,
speed in long.,
speed in lat.,
and speed in dist.
serr = character string to return error messages in case of error.
——————————————————————————————

Насколько понятно из описания, возвращаемое значение функции - всего лишь флаг, сообщающий о наличии/отстутствии ошибок, а нужные данные после выполнения функции надо будет считывать из массива xx

Ссылки:
Описание функции: http://www.astro.com/swisseph/swephprg.htm#_Toc283735419
Пример ее использования в Си: http://www.astro.com/swisseph/swephprg.htm#_Toc283735418
Андрей Светлов
сравните
ret_flag = swedll.swe_calc_ut(c_int(jul_day_UT), c_int(1), c_int(0), byref(arr), byref(sErr))
и
int swe_calc_ut ( double tjd_ut, int ipl, int iflag, double* xx, char* serr);
streetmover
Андрей Светлов
Спасибо, исправил, эта ошибка исчезла.
streetmover
Но код все еще не заработал.

from ctypes import *
from array import array

swedll = windll.swedll32

************************************************************
# вызов функции swedll.swe_julday() проходит нормально
#************************************************************
sName = ""
sName = swedll.swe_get_planet_name(1, sName)
jul_day_UT = 0
jul_day_UT = swedll.swe_julday(2011, 4, 23, c_double(0.10), 1)
print "jul_day_UT: ", jul_day_UT


#************************************************************
# вызов функции swe_calc_ut() не работает
#************************************************************
arr_lst = [30.0, 40.0, 0.0, 0.0, 0.0, 0.0 ]
arr_type = c_double * len(arr_lst)
arr = arr_type(*arr_lst)
sErr = create_string_buffer(256)

ret_flag = swedll.swe_calc_ut(c_double(jul_day_UT), c_int(1), c_int(0), byref(arr), byref(sErr))
print "ret_flag: ", ret_flag
for i in arr: print i

#********************************************************************
swedll.swe_close()
При выполнении выводится только:
jul_day_UT: 14368

Теоретически, на экране должна появляться еще хотя бы эта строка:
ret_flag:
Но ни она, ни значения переменной ret_flag и значения массива arr последними операторами print не выводятся.

То есть, такое впечатление, что попытка выполненить функцию swe_calc_ut нарушает работу всего питоновского интерпретатора, или, по крайней мере - модуля, отвечающего за вывод. Причем, скорее всего, нарушается работа именно интерпретатора, так как если в Windows XP просто наблюдается вышеописанный эффект, то Windows Vista кроме этого, еще ругается на работу программы и предлагает закрыть ее.
Андрей Светлов
А вы уверены, что swedll32 именно windll? Без дополнительных указаний VC генерирует код с соглашениями вызова cdecl а не stdcall.
Для ctypes это будет cdll.
streetmover
Андрей Светлов
А вы уверены, что swedll32 именно windll?
Для ctypes это будет cdll.
Уверенности не было, просто с cdll - вообще сыпались одни ошибки, и были сообщения, что функции в dll не находятся, поэтому от этого варианта пришлось отказаться.

Все, код питона заработал в варианте с windll, причем причиной было, как ни странно - отсутствие строки с обозначением кодировки модуля. Заработало после того как первой строкой в скрипт было добавлено:
# -*- coding: cp1251 -*-
То есть теперь функция swe_calc_ut заработала, значение возвратила, и все питоновские операторы print выводят значения на консоль.

Правда значения переменных не те, что хотелось бы получить, и появились сообщения об ошибках, выдаваемые самой dll в параметр sErr и связанные со спецификой функционала этой самой библиотеки, но это уже не тема данного форума, с этим буду бороться другими средствами.
Андрей Светлов
Кодировка причиной ошибки быть не может. Это — наверняка.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB