之前,发过一篇同样的博文,记录了编译傅立叶变换FFTW_2.1.5的方法:C++学习 | Windows下FFTW_2.1.5的编译及使用。
今天用的时候发现,上次编译的是64位的,不能在32位环境下调用,因此我重新编译了一版32位的dll。
将编译过程记录下来,供有需要的朋友参考。
1.方法一
采用C++学习 | Windows下FFTW_2.1.5的编译及使用 中的方法,只是在编译时采取32位的模式。
2.方法二
由于我的笔记本中没有安装MSYS2,又不想安装,所以采用笔记本中已有的TDM-GCC-64的编译器进行编译,关于TDM-GCC-64的安装可以自行百度查找,此处不再赘述。
gcc总体选项列表
1) -c :指编译,不链接,生成目标文件“.o”。
2) -S :只编译,不汇编,生成汇编代码“.S”。
3) -E :只进行预编译/预处理,不做其他处理。
4) -o file:把输出文件输出到file里。
5) -g :在可执行程序中包含标准调试信息。
6) -v :打印出编译器内部编译各过程的命令行信息和编译器的版本。
7) -I dir :在头文件的搜索路径列表中添加dir目录
8) -L dir :在库文件的搜索路径列表中添加dir目录
9) -static :连接静态库(静态库也可以用动态库链接方式链接)
10) -llibrary :连接名为library的库文件(显示指定需要链接的动态库文件)
编译过程如下:
(1)打开fftw所在目录
(2)使用gcc命令编译
当我试图采用如下命令编译时,出现了图中所示错误
gcc *.c -shared -o fftw2.dll -Wl,--output-def,fftw2.def
百度了一圈以后,并没有找到windows下使用gcc编译多个源文件的快捷方法,只好采用笨方法,将目录下的所有.c源文件一一加进去。
使用如下命令得到目录下的所有.c文件
dir /b *.c>cList.txt
将文件名复制过来重新写gcc命令,如下:
gcc config.c executor.c fftwf77.c fftwnd.c fni_1.c fni_10.c fni_11.c fni_12.c fni_13.c fni_14.c fni_15.c fni_16.c fni_2.c fni_3.c fni_32.c fni_4.c fni_5.c fni_6.c fni_64.c fni_7.c fni_8.c fni_9.c fn_1.c fn_10.c fn_11.c fn_12.c fn_13.c fn_14.c fn_15.c fn_16.c fn_2.c fn_3.c fn_32.c fn_4.c fn_5.c fn_6.c fn_64.c fn_7.c fn_8.c fn_9.c ftwi_10.c ftwi_16.c ftwi_2.c ftwi_3.c ftwi_32.c ftwi_4.c ftwi_5.c ftwi_6.c ftwi_64.c ftwi_7.c ftwi_8.c ftwi_9.c ftw_10.c ftw_16.c ftw_2.c ftw_3.c ftw_32.c ftw_4.c ftw_5.c ftw_6.c ftw_64.c ftw_7.c ftw_8.c ftw_9.c generic.c malloc.c planner.c putils.c rader.c timer.c twiddle.c wisdom.c wisdomio.c -m32 -shared -o fftw2_win32.dll -Wl,--output-def,fftw2_win32.def
其中,-m32表示生成32位机器的汇编代码。-m64表示生成64位机器的汇编代码。
上面的命令运行完成后,即可在目录下生成fftw2_win32.dll和fftw2_win32.def
(3)使用vs自带的命令提示工具编译生成.lib文件
用vs(Visual Studio)自带的命令提示编译,我用的是vs2008。
进入dll文件所在文件夹目录
输入命令:lib /machine:X86 /def:fftw2.def
回车即可生成.lib文件
其中X86表示生成32位机器的汇编代码,X64表示生成64位机器的汇编代码。
至此,编译成功!
3.实例测试
我在VS 2008中采用如下的一段代码对上述生成的fftw2_win32作了测试,环境为win32。
#include <stdlib.h>
#include <time.h>
#include "fftw2.h"
int main()
{
fftw_complex *in, *out;
int N = 10;
in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N);
out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N);
printf("Original array:\n");
for (int i = 0; i < N; i++)
{
c_re(in[i]) = 1.0;
c_im(in[i]) = 0.0;
printf("%6.2f ", in[i].re);
}
printf("\n");
// 傅里叶正变换
clock_t start = clock();
fftw_plan p;
p = fftw_create_plan(N, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_one(p, in, out);
printf("\nFourier transform array:\n");
for (int j = 0; j < N; j++)
{
printf("%6.2f ", out[j].re);
}
clock_t end = clock();
printf("\n");
printf(" FFTW : %f second\n", (double)(end - start) / CLOCKS_PER_SEC);
// 傅里叶反变换
fftw_plan q = fftw_create_plan(N, FFTW_BACKWARD, FFTW_ESTIMATE);
fftw_complex *out2 = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N);
fftw_one(q, out, out2);
printf("\nInverse fourier transform array:\n");
for (int j = 0; j < N; j++)
{
printf("%6.2f ", out2[j].re/N); // 反变换需要除以数组长度
}
printf("\n");
fftw_destroy_plan(p);
fftw_destroy_plan(q);
fftw_free(in);
fftw_free(out);
fftw_free(out2);
system("PAUSE");
return 0;
}
编译成功,并输出了正确结果。
-- END --