FFTW и Visual Studio 2008 [FIXED]

vnk02

Необходимо осуществлять вызов подпрограмм быстрого преобразования Фурье
из программы на Fortran'е. Разработка в Visual Studio 2008, компилятор Intel Fortran 11.0.072.
Разработчики поставляют откомпилированные для WinXP *.dll файлы и к ним *.def.
В интернетах вычитал, что надо из этих *.def с помощью команды lib компилятора сделать
*.lib для того чтобы программа могла вызывать функции прошитые в .dll
Из командной строки intel fortran выполнил
lib /machine:i386 /def:libfftw3-3.def
получил libfftw3-3.lib
Теперь вопрос - как правильно привязать
эти *.lib к программе, чтобы она "видела" зашитые функции.
Пробовал два варианта:
1. Непосредственно подключал файлы .lib к проекту:
Project - Add Existing Item...
2. Подкидывал .lib в каталог библиотек intel fortran
C:\Program Files\Intel\Compiler\11.0\072\fortran\lib\ia32
и в свойствах проекта указывал
Linker - input - Additional Dependencies
имя библиотеки
а в Linker - General - Additional Library Directoties на всякий случай
и путь C:\Program Files\Intel\Compiler\11.0\072\fortran\lib\ia32
Результат линкирования
программы вида
*****************************************
program FFTWexp
include 'fftw3.f'
integer(4parameter::N = 1024
integer*8::plan
complex,dimension(1:N)::in, out
call dfftw_plan_dft_1d(plan,N,in,out,FFTW_FORWARD,FFTW_ESTIMATE)
call dfftw_destroy_plan(plan)
pause
end program FFTWexp
*********************************************
выдает ошибки
Error 1 error LNK2019: unresolved external symbol _DFFTW_PLAN_DFT_1D referenced in function _MAIN__ FFTWexp.obj
Error 2 error LNK2019: unresolved external symbol _DFFTW_DESTROY_PLAN referenced in function _MAIN__ FFTWexp.obj
Error 3 fatal error LNK1120: 2 unresolved externals Debug\FFTWexp.exe
Вопрос: что это может быть, что я делаю неправильно?
Заранее спасибо)
 

vnk02

Вот еще ссылка на сайт, советы с которого я использовал
http://www.math.ucla.edu/~anderson/270e.1.08f/Assign5/Assign...

Serab

Дай вценить def-файл.

vnk02

Файл достаточно большой.
Вот только часть
LIBRARY libfftw3-3.dll
EXPORTS
dfftw_cleanup_
dfftw_cleanup__
dfftw_cleanup_threads_
dfftw_cleanup_threads__
dfftw_destroy_plan_
dfftw_destroy_plan__
dfftw_execute_
dfftw_execute__
dfftw_execute_dft_
dfftw_execute_dft__
dfftw_execute_dft_c2r_
dfftw_execute_dft_c2r__
dfftw_execute_dft_r2c_
dfftw_execute_dft_r2c__
dfftw_execute_r2r_
dfftw_execute_r2r__
dfftw_execute_split_dft_
dfftw_execute_split_dft__
dfftw_execute_split_dft_c2r_
dfftw_execute_split_dft_c2r__
dfftw_execute_split_dft_r2c_
dfftw_execute_split_dft_r2c__
dfftw_export_wisdom_
dfftw_export_wisdom__
dfftw_flops_
dfftw_flops__
dfftw_forget_wisdom_
dfftw_forget_wisdom__
dfftw_import_system_wisdom_
dfftw_import_system_wisdom__
dfftw_import_wisdom_
dfftw_import_wisdom__
dfftw_init_threads_
dfftw_init_threads__
dfftw_plan_dft_
dfftw_plan_dft_1d_
dfftw_plan_dft_1d__
dfftw_plan_dft_2d_
dfftw_plan_dft_2d__
dfftw_plan_dft_3d_
dfftw_plan_dft_3d__
dfftw_plan_dft__
dfftw_plan_dft_c2r_
dfftw_plan_dft_c2r_1d_
dfftw_plan_dft_c2r_1d__
dfftw_plan_dft_c2r_2d_
dfftw_plan_dft_c2r_2d__
dfftw_plan_dft_c2r_3d_
dfftw_plan_dft_c2r_3d__
dfftw_plan_dft_c2r__
dfftw_plan_dft_r2c_
dfftw_plan_dft_r2c_1d_
dfftw_plan_dft_r2c_1d__
dfftw_plan_dft_r2c_2d_
dfftw_plan_dft_r2c_2d__
dfftw_plan_dft_r2c_3d_
dfftw_plan_dft_r2c_3d__
dfftw_plan_dft_r2c__
dfftw_plan_guru_dft_
dfftw_plan_guru_dft__
dfftw_plan_guru_dft_c2r_
dfftw_plan_guru_dft_c2r__
dfftw_plan_guru_dft_r2c_
dfftw_plan_guru_dft_r2c__
dfftw_plan_guru_r2r_
dfftw_plan_guru_r2r__
dfftw_plan_guru_split_dft_
dfftw_plan_guru_split_dft__
dfftw_plan_guru_split_dft_c2r_
dfftw_plan_guru_split_dft_c2r__
dfftw_plan_guru_split_dft_r2c_
dfftw_plan_guru_split_dft_r2c__
dfftw_plan_many_dft_
dfftw_plan_many_dft__
dfftw_plan_many_dft_c2r_
dfftw_plan_many_dft_c2r__
dfftw_plan_many_dft_r2c_
dfftw_plan_many_dft_r2c__
dfftw_plan_many_r2r_
dfftw_plan_many_r2r__
dfftw_plan_r2r_
dfftw_plan_r2r_1d_
dfftw_plan_r2r_1d__
dfftw_plan_r2r_2d_
dfftw_plan_r2r_2d__
dfftw_plan_r2r_3d_
dfftw_plan_r2r_3d__
dfftw_plan_r2r__
dfftw_plan_with_nthreads_
dfftw_plan_with_nthreads__
dfftw_print_plan_
dfftw_print_plan__

Serab

ага, ок.
Теперь так: зайди в Пуск->Programs->Visual Studio 2008->Visual Studio Tools->Visual Studio 2008 Command Prompt.
Оттуда введи
dumpbin /exports "путь к файлу .dll в кавычках"

Там будет примерно столько же текста. Тоже скопируй сюда вывод. Можно просто строк 10 :)

vnk02

Вот результат
1 0 000A8109 DFF0
2 1 0011E0FB DFFTW_CLEAN0
3 2 000A80F2 DFFTW_DE4
4 3 000A80D0 DFF4
5 4 000A8690 DFFTW_E12
6 5 000A9091 DFFTW_EXECU12
7 6 000A8B96 DFFTW_EXECU12
8 7 000A95E2 DFFTW_E12
9 8 000A86F3 DFFTW_EXECUTE20
10 9 000A90DD DFFTW_EXECUTE_SPL16

Serab

Попробуй в той программе снести лишнее и вызвать dfftw_cleanup и закомпилить.

vnk02

результат тот же
Error 1 error LNK2019: unresolved external symbol _DFFT_CLEANUP referenced in function _MAIN__ FFTWexp.obj

Serab

А, подожди-ка.
Ты в Additional Dependencies имя какой библиотеки добавил? Туда надо lib добавлять.

Serab

Хотя, прочитав еще раз первый пост, понял, что скорее всего ты правильно сделал.

vnk02

там вроде так и прописано libfftw3-3.lib,
мистика)

Serab

У меня плохое предчувствие, что тут надо знать механизмы декорации имен именно у компилятора фортрана. У меня сейчас на изучение этого нет сил :crazy:
Странно, что у экспортируемых функций имена выглядят как number. В Си, например, они бы выглядели number. Еще странно, что судя по выводу dumpbin dll-ка вообще с def-файлом не компилировалась.
Ладно, такая телепатия: поищи в настройках _компилятора_ Intel (там же, в настройках проекта должна быть соответствующая категория, рядом с Linker и C/C++ ищи в направлении calling conventions или типа того. Или name decoration. Все, что с этим связано — напиши.

Serab

Кстати, посмотри внимательнее на вывод dumpbin, нет ли там имен функций без значка собаки

Serab

Да, вот скажи, ты знаешь каким компилятором эта dll-ка компилировалась?

vnk02

Разработчики пишут, что
These DLLs were created by us, cross-compiled from GNU/Linux using MinGW
в выводе dumpbin есть еще и такое ниже
47 2E 000A663D dfftw_cleanup_
48 2F 000A4B7B dfftw_cleanup__
49 30 0011E0CB dfftw_cleanup_threads_
50 31 0011E0A5 dfftw_cleanup_threads__
51 32 000A662E dfftw_destroy_plan_
52 33 000A4B6C dfftw_destroy_plan__
53 34 000A660E dfftw_execute_
54 35 000A4B4C dfftw_execute__
55 36 000A6D47 dfftw_execute_dft_
56 37 000A5285 dfftw_execute_dft__
57 38 000A7A32 dfftw_execute_dft_c2r_
58 39 000A5F70 dfftw_execute_dft_c2r__
59 3A 000A73C1 dfftw_execute_dft_r2c_
60 3B 000A58FF dfftw_execute_dft_r2c__
61 3C 000A80AA dfftw_execute_r2r_
62 3D 000A65E8 dfftw_execute_r2r__
63 3E 000A6DA6 dfftw_execute_split_dft_
64 3F 000A52E4 dfftw_execute_split_dft__
65 40 000A7A7C dfftw_execute_split_dft_c2r
66 41 000A5FBA dfftw_execute_split_dft_c2r
67 42 000A740B dfftw_execute_split_dft_r2c
68 43 000A5949 dfftw_execute_split_dft_r2c
69 44 000A6647 dfftw_export_wisdom_
70 45 000A4B85 dfftw_export_wisdom__
71 46 000A66DA dfftw_flops_
72 47 000A4C18 dfftw_flops__
73 48 000A6642 dfftw_forget_wisdom_
74 49 000A4B80 dfftw_forget_wisdom__
75 4A 000A66A3 dfftw_import_system_wisdom_
76 4B 000A4BE1 dfftw_import_system_wisdom_
77 4C 000A6672 dfftw_import_wisdom_
78 4D 000A4BB0 dfftw_import_wisdom__
79 4E 0011E0B9 dfftw_init_threads_
80 4F 0011E093 dfftw_init_threads__
81 50 000A66E9 dfftw_plan_dft_
82 51 000A6796 dfftw_plan_dft_1d_
83 52 000A4CD4 dfftw_plan_dft_1d__
84 53 000A67D5 dfftw_plan_dft_2d_
85 54 000A4D13 dfftw_plan_dft_2d__
86 55 000A681E dfftw_plan_dft_3d_
87 56 000A4D5C dfftw_plan_dft_3d__
88 57 000A4C27 dfftw_plan_dft__
89 58 000A744B dfftw_plan_dft_c2r_
90 59 000A74E7 dfftw_plan_dft_c2r_1d_
91 5A 000A5A25 dfftw_plan_dft_c2r_1d__
92 5B 000A751C dfftw_plan_dft_c2r_2d_
93 5C 000A5A5A dfftw_plan_dft_c2r_2d__
94 5D 000A755B dfftw_plan_dft_c2r_3d_
95 5E 000A5A99 dfftw_plan_dft_c2r_3d__
96 5F 000A5989 dfftw_plan_dft_c2r__
97 60 000A6DDA dfftw_plan_dft_r2c_
98 61 000A6E76 dfftw_plan_dft_r2c_1d_
99 62 000A53B4 dfftw_plan_dft_r2c_1d__
100 63 000A6EAB dfftw_plan_dft_r2c_2d_
101 64 000A53E9 dfftw_plan_dft_r2c_2d__
102 65 000A6EEA dfftw_plan_dft_r2c_3d_
103 66 000A5428 dfftw_plan_dft_r2c_3d__
104 67 000A5318 dfftw_plan_dft_r2c__
105 68 000A6A44 dfftw_plan_guru_dft_
106 69 000A4F82 dfftw_plan_guru_dft__
107 6A 000A7762 dfftw_plan_guru_dft_c2r_
108 6B 000A5CA0 dfftw_plan_guru_dft_c2r__
109 6C 000A70F1 dfftw_plan_guru_dft_r2c_
110 6D 000A562F dfftw_plan_guru_dft_r2c__
111 6E 000A7EE2 dfftw_plan_guru_r2r_
112 6F 000A6420 dfftw_plan_guru_r2r__
113 70 000A6BBD dfftw_plan_guru_split_dft_
114 71 000A50FB dfftw_plan_guru_split_dft__
115 72 000A78BA dfftw_plan_guru_split_dft_c
116 73 000A5DF8 dfftw_plan_guru_split_dft_c
117 74 000A7249 dfftw_plan_guru_split_dft_r
118 75 000A5787 dfftw_plan_guru_split_dft_r
119 76 000A6871 dfftw_plan_many_dft_
120 77 000A4DAF dfftw_plan_many_dft__
121 78 000A75A4 dfftw_plan_many_dft_c2r_
122 79 000A5AE2 dfftw_plan_many_dft_c2r__
123 7A 000A6F33 dfftw_plan_many_dft_r2c_
124 7B 000A5471 dfftw_plan_many_dft_r2c__
125 7C 000A7CAB dfftw_plan_many_r2r_
126 7D 000A61E9 dfftw_plan_many_r2r__
127 7E 000A7ABC dfftw_plan_r2r_
128 7F 000A7BB2 dfftw_plan_r2r_1d_
129 80 000A60F0 dfftw_plan_r2r_1d__
130 81 000A7BF1 dfftw_plan_r2r_2d_
131 82 000A612F dfftw_plan_r2r_2d__
132 83 000A7C44 dfftw_plan_r2r_3d_
133 84 000A6182 dfftw_plan_r2r_3d__
134 85 000A5FFA dfftw_plan_r2r__
135 86 0011E0AA dfftw_plan_with_nthreads_
136 87 0011E084 dfftw_plan_with_nthreads__
137 88 000A66B5 dfftw_print_plan_
138 89 000A4BF3 dfftw_print_plan__
139 8A 000011DC fftw_assertion_failed
140 8B 0012B1C0 fftw_cc
141 8C 000AB487 fftw_cleanup

banderon

В Фортране по жизни какие-то траблы с подчёркиваниями. Обычно к фортрановским именам надо добавлять "_" в конец если хочешь вызвать функцию из Си, например. Если в названии функции где-то в середине уже есть "_", то всё ещё сложнее, иногда приходится добавлять два "__". Может тут где-то в этом косяк?
Хотя в твоём выводе вроде все имена продублированы с одним "_" и с двумя "__" на конце, так что подхватываться должны вроде как… Странно, но я бы всё равно попробовал поковыряться с разными вариациями "_" на конце, вдруг?

Serab

косяк с подчеркиваниями — это декорация имен (Name mangling, тут можешь прочитать).
Нет, вот на что надо обратить внимание: линковщик уже ничего не знает о языке, он ищет функцию _DFFTW_PLAN_DFT_1D и не может найти. Странно то, что подчеркивание стоит перед именем, хотя на википедии (ха-ха) утверждается, что для интеловского компилятора фортрана это не свойственно. Но это именно он должно быть так поступил. Поэтому все-таки надо порыться в его настройках, может быть там по умолчанию какой-то левый режим совместимости включен или еще чего. Посмотри настройки про name decoration/mangling. По идее это должно быть в свойствах проекта (я выше писал)

Serab

А, не заметил, что собеседник новый появился, в общем обращался я к топикстартеру в этом посте.

vnk02

нашел в help
iface - Specifies the default calling convention and argument-passing convention for an application.
разбираюсь

Serab

Скорее всего когда разберешься, заработает. Я пошел :D

vnk02

Уперся я в итоге в следующее
при любом выборе настроек /iface
в конвенции имен предполагается, что перед именем стоит подчеркивание _
но как мы видели из листинга dumpbin
имена присутствуют только без первого подчеркивания
В сообщениях об ошибках мы как раз и видим, что линкер
пытается найти процедуру с подчеркиванием
Error 1 error LNK2019: unresolved external symbol _DFFTW_CLEANUP referenced in function _MAIN__ FFTWexp.obj
Опции, управляющей первым подчеркиванием я не нашел.
Попытка в программе писать
call _DFFTW_CLEANUP
приводит к Error 1 error Lead underscore not allowed
Что можно в таком случае сделать?

asvsergey

By default, FFTW configures its Fortran interface to work with the first compiler it finds, e.g. g77. To configure for a different, incompatible Fortran compiler foobar, use ./configure F77=foobar when installing FFTW. (In the case of g77, however, FFTW 3.x also includes an extra set of Fortran-callable routines with one less underscore at the end of identifiers, which should cover most other Fortran compilers on Linux at least.)

Это делал?

vnk02

Этого я не делал. Я так понял, что использовать configure надо, если я хочу сам перекомпилить весь FFTW.
Вообще авторы предлагают концепцию самому перекомпилиь
MinGW: this is a free Unix-like environment for Windows based on the GNU C compiler (gcc). We recommend this route because it produces native Windows executables/libraries, but lets you use our standard Unix build scripts and Makefiles, automatically picks good compiler flags, and so on. See below for instructions
я даже установил этот MinGW, но вот как с ним обращаться, где эту команду ./configure писать я не представляю.
Как я уже писал постом выше, проблема, мне кажется, в том, чтобы откомпилировать так, чтобы
перед именами функций прошитых в .dll стояли бы подчеркивания. Но и как это сделать я не представляю (даже если бы я умел работать с MinGW)

Serab

Как я уже писал постом выше, проблема, мне кажется, в том, чтобы откомпилировать так, чтобы
перед именами функций прошитых в .dll стояли бы подчеркивания. Но и как это сделать я не представляю (даже если бы я умел работать с MinGW)
Ты же dll не можешь перекомпилить. В ней имена как раз соответствуют тому декорированию, информацию о котором я смог найти (да, на википедии а вот твой компилятор декорирует по-сишному. Вот мне и кажется, что он так декорирует, чтобы было удобнее обращаться к функциям, написанным на C, т.е. якобы для "лошков"
Обрати внимание еще на одну вещь: дело не только в подчеркивании, но и в регистре символов, он их за тебя капитализировал (потому что Fortran — case-insensitive, а тот же C — case-sensitive, и можно по-разному это реализовывать. Википедия пишет, что обычно фортрановские функции декорируют приведением к нижнему регистру и дописыванием подчеркивания в конец, у тебя же мы видим приведение к верхнему регистру и дописывание подчеркивания в начало, вот это и надо поправить: В НАСТРОЙКАХ КОМПИЛЯЦИИ ТВОЕЙ ПРОГРАММЫ)

Serab

Кстати, если бы КОНТРА сейчас заглядывал в форум, он бы мог предложить текстовую замени имен _ТАКОГО_ВИДА к именам такого_вида_ перед передачей файла линковщику, например, программкой sed.

vnk02

В настройках компилятора, судя по help нет возможности убрать переднее подчеркивание в случае если
программа делается для win32.
Однако, если целевая платформа Win64, то он не дописывает ни переднего подчеркивания
ни @, ни подчеркивания сзади.
В win64 *.dll
имена такие
0 000DCD8F DFFTW_CLEANUP
1 00145CD0 DFFTW_CLEANUP_THREADS
2 000DCDB6 DFFTW_DESTROY_PLAN
3 000DC0CA DFFTW_EXECUTE
4 000DC0E5 DFFTW_EXECUTE_DFT
5 000DC1AF DFFTW_EXECUTE_DFT_C2R
6 000DC146 DFFTW_EXECUTE_DFT_R2C
7 000DC21E DFFTW_EXECUTE_R2R
8 000DC12E DFFTW_EXECUTE_SPLIT_DFT
9 000DC1E7 DFFTW_EXECUTE_SPLIT_DFT_C2R
A 000DC17B DFFTW_EXECUTE_SPLIT_DFT_R2C
т.е. все вроде бы нормально. Однако на
call DFFTW_CLEANUP
та же ругань
Error 1 error LNK2019: unresolved external symbol DFFTW_CLEANUP referenced in function MAIN__ FFTWexpx64.obj
Вот это вообще абзац.
Я видимо до дачи, спасибо за содержательные ответы, вернусь вечером.

Serab

регистр не совпадает же, в этом и беда.
Ладно, всегда остается вариант скомпилить в асм (или декомпилить объектник, заменить имена, закомпилить обратно и передать линкеру, но это для мужчин с железными яйцами =)

Serab

Хотя я что-то тупанул, регистр же совпадает :D
Ты lib-файл перегенерировал, когда с win64-dll пробовал? Во время компиляции файл dll вообще не используется.

polpot

все правильно, дело в регистре, а не в подчеркивании перед именем.
регистр можно поменять в project properties/fortran/external procedures/name case interpretation
Чтобы работало надо:
1) поставь там lowercase
2) там же в настройках добавить нижнее подчеркивание после каждого имени
только что проверено и на 32 и на 64 битах.
И не забудь откомпилить библиотеку из соответствующих разрядности .def файлов для fftw

vnk02

Всем спасибо, проблему решил Maver
Выводы:
В настройках проекта
Fortran -> External Procedures -> Name Case Interpretation -> Lower Case (/names:lowercase)
Fortran -> External Procedures -> Append Underscore to External Names -> Yes(/assume:underscore)
не забыть кинуть *.dll в Windows\system32\
или в свойствах проекта
Debugging -> Environment
PATH=%PATH%;Path to the folder containing libfftw3-3.dll
Еще раз всем спасибо за содержательную дискуссию

Serab

В настройках проекта
Fortran -> External Procedures -> Name Case Interpretation -> Lower Case (/names:lowercase)
Fortran -> External Procedures -> Append Underscore to External Names -> Yes(/assume:underscore)
Я же тебе про это писал с самой середины. Ладно, я рад :D
Оставить комментарий
Имя или ник:
Комментарий: