Уведомления

Группа в Telegram: @pythonsu

#1 Май 9, 2011 08:25:34

streetmover
От:
Зарегистрирован: 2010-06-25
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Вызов функции из dll

Доброго времени суток всем и с праздником.

Проблема при вызове функции из 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



Офлайн

#2 Май 9, 2011 19:31:08

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Вызов функции из dll

сравните
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);



Офлайн

#3 Май 9, 2011 21:23:24

streetmover
От:
Зарегистрирован: 2010-06-25
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Вызов функции из dll

Андрей Светлов
Спасибо, исправил, эта ошибка исчезла.



Офлайн

#4 Май 9, 2011 21:42:57

streetmover
От:
Зарегистрирован: 2010-06-25
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Вызов функции из 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_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 кроме этого, еще ругается на работу программы и предлагает закрыть ее.



Отредактировано (Май 9, 2011 21:46:29)

Офлайн

#5 Май 10, 2011 08:37:09

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Вызов функции из dll

А вы уверены, что swedll32 именно windll? Без дополнительных указаний VC генерирует код с соглашениями вызова cdecl а не stdcall.
Для ctypes это будет cdll.



Офлайн

#6 Май 10, 2011 22:11:19

streetmover
От:
Зарегистрирован: 2010-06-25
Сообщения: 25
Репутация: +  0  -
Профиль   Отправить e-mail  

Вызов функции из dll

Андрей Светлов
А вы уверены, что swedll32 именно windll?
Для ctypes это будет cdll.
Уверенности не было, просто с cdll - вообще сыпались одни ошибки, и были сообщения, что функции в dll не находятся, поэтому от этого варианта пришлось отказаться.

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

Правда значения переменных не те, что хотелось бы получить, и появились сообщения об ошибках, выдаваемые самой dll в параметр sErr и связанные со спецификой функционала этой самой библиотеки, но это уже не тема данного форума, с этим буду бороться другими средствами.



Офлайн

#7 Май 10, 2011 23:22:49

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Вызов функции из dll

Кодировка причиной ошибки быть не может. Это — наверняка.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version