VC++编译MPIR 2.7.0

目录

第1章编译    2

1.1 简介    2

1.2 下载    3

1.3 解决方案    4

1.4 创建项目    5

1.5 复制文件树    6

1.6 不使用预编译头文件    8

1.7 包含目录    9

1.8 定义宏    10

1.9 编译前事件    11

1.10 修改 obj 的位置    13

1.11 编译yasm    14

1.12 编译汇编代码    15

1.12.1 Custom Build    15

1.12.2 .rules文件    17

1.12.3 .targets文件    20

1.13 替换long long    23

1.14 strnlen函数    23

 

 

第1章编译

1.1 简介

MPIR 是一个开源的多精度整数和有理数计算库,基于 GMP 库开发。它有什么用呢?

如下图所示,笔者在推导缓和曲线弦长随弧长变化的函数时,得到了一个递推公式。

图1.1

递推公式如下:

可见的计算只涉及到分数(有理数)的四则运算,是比较简单的。只是随着的增大,运算量越来越大,手工计算会越来越困难。

上述公式可以编程实现。C/C++的基本数据类型中,使用double表示是比较恰当的。double是有误差的,而且的计算误差会积累,随着的增大的计算误差会越来越大。

借助MPIR的有理数计算功能,可以解决上述问题。的前几项见下表:

n

系数

0

1

1

-1/90

2

1/22680

3

-79/2043241200

4

2633/12504636144000

5

1215749/1646485441080480000

6

48316241/15905049360837436800000

7

193921367/49059847710292202784000000

8

-73267589502073/927478383356982505319631360000000

MPIR是从GMP移植而来的。因为GMP主要是针对于Unix、Linux操作系统的,使用VC++编译比较困难。MPIR的主要工作其实就是把GMP移植到Windows操作系统,使得VC++能够编译。

1.2 下载

浏览网址http://www.mpir.org/,下载mpir-2.7.0.zip,然后解压到W:\mpir\v2.7.0\mpir。目录结构如下图所示:

图1.2

1.3 解决方案

mpir 2.7.0自带了四个Visual Studio 解决方案,如下所示:

W:\mpir\v2.7.0\mpir\build.vc10\mpir.sln            使用vc2010打开

W:\mpir\v2.7.0\mpir\build.vc11\mpir.sln            使用vc2012打开

W:\mpir\v2.7.0\mpir\build.vc12\mpir.sln            使用vc2013打开

W:\mpir\v2.7.0\mpir\build.vc14\mpir.sln            使用vc2015打开

使用vc2010打开mpir.sln后,可以看到有七个项目,如下图所示:

图1.3

这七个项目的区别如下:

dll_mpir_gc        生成动态库,不使用汇编代码

dll_mpir_p3        生成动态库,含32位汇编代码(奔腾3)

dll_mpir_core2        生成动态库,含64位汇编代码(酷睿2)

lib_mpir_cxx        生成静态库,不使用汇编代码

lib_mpir_gc        生成静态库,不使用汇编代码

lib_mpir_p3        生成静态库,含32位汇编代码(奔腾3)

lib_mpir_core2        生成静态库,含64位汇编代码(酷睿2)

mpir有两套API:C API和C++ API。前者可用于C和C++,后者只能用于C++。lib_mpir_gc、lib_mpir_p3、lib_mpir_core2只含有C API;lib_mpir_cxx只含有C++ API;dll_mpir_gc、dll_mpir_p3、dll_mpir_core2既有C API又有C++ API。

从兼容性考虑,建议不要使用汇编代码。只有在对速度要求特别高的情况下,需要考虑使用汇编代码。

1.4 创建项目

为了使用vc6~vc2008编译mpir 2.7.0,需要创建项目。

笔者在W:\mpir\v2.7.0\vc目录下创建了11个目录,如下图所示。

make-dll-c        将创建动态库,只使用c语言

make-dll-asm32        将创建动态库,使用32位汇编代码

make-dll-asm64        将创建动态库,使用64位汇编代码

make-libS-*        将创建静态库,C运行时库为单线程

make-libT-*        将创建静态库,C运行时库为多线程

make-libD-*        将创建静态库,C运行时库为多线程DLL

 

图1.4

每个目录下,又有多个子目录,如下图所示。如:使用vc6编译请进入vc6目录。

图1.5

1.5 复制文件树

W:\mpir\v2.7.0\mpir\build.vc10\mpir.sln里每个项目都有文件树。如下图所示。现在要把这些项目的文件树复制到上一节新建的项目里。

图1.6

可以手工添加,只不过五百多个文件添加起来还是很繁琐的。可以使用vcHelper来完成此项繁琐的工作。如下图所示,vcHelper把W:\mpir\v2.7.0\mpir\build.vc10\dll_mpir_gc\dll_mpir_gc.vcxproj里的文件树复制到W:\mpir\v2.7.0\vc\make-dll-c\vc6\mpir.dsp。

图1.7

需要复制的文件树如下表所示:

从 W:\mpir\v2.7.0\mpir\build.vc10\dll_mpir_gc\dll_mpir_gc.vcxproj 复制到

W:\mpir\v2.7.0\vc\make-dll-c\vc6\mpir.dsp

W:\mpir\v2.7.0\vc\make-libD-c\vc6\mpirD.dsp

W:\mpir\v2.7.0\vc\make-libS-c\vc6\mpirS.dsp

W:\mpir\v2.7.0\vc\make-libT-c\vc6\mpirT.dsp

从 W:\mpir\v2.7.0\mpir\build.vc10\dll_mpir_p3\dll_mpir_p3.vcxproj 复制到

W:\mpir\v2.7.0\vc\make-dll-asm32\vc6\mpir.dsp

W:\mpir\v2.7.0\vc\make-libD-asm32\vc6\mpirD.dsp

W:\mpir\v2.7.0\vc\make-libS-asm32\vc6\mpirS.dsp

W:\mpir\v2.7.0\vc\make-libT-asm32\vc6\mpirT.dsp

从 W:\mpir\v2.7.0\mpir\build.vc10\dll_mpir_core2\dll_mpir_core2.vcxproj 复制到

W:\mpir\v2.7.0\vc\make-dll-asm64\vc2008\mpir.dsp

W:\mpir\v2.7.0\vc\make-libD-asm64\vc2008\mpirD.dsp

W:\mpir\v2.7.0\vc\make-libS-asm64\vc2008\mpirS.dsp

W:\mpir\v2.7.0\vc\make-libT-asm64\vc2008\mpirT.dsp

vcHelper的下载:访问http://pan.baidu.com/s/1gd7XDkf 然后进入public\Tools\vcHelper下载压缩包。

1.6 不使用预编译头文件

设置VC++,编译时不使用预编译头文件。

VC++6.0的设置如下图所示:

图1.8

VC++.NET的设置如下图所示:

图1.9

1.7 包含目录

编译.c文件时,需要文件W:\mpir\v2.7.0\mpir\mpir.h。该文件相对于VC++6.0项目文件(W:\mpir\v2.7.0\vc\make-dll-c\vc6\mpir.dsp)的相对路径为../../../mpir

VC++6.0的具体配置如下:

图1.10

VC++.NET的配置如下

图1.11

1.8 定义宏

需要定义宏:HAVE_CONFIG_H,不过它似乎没有什么实质作用。

编译生成动态库,还需要定义宏MSC_BUILD_DLL。它用来导出mpir的API函数。

VC++6.0的配置如下:

图1.12

VC++.NET的配置如下。vc2002~vc2008不能选择All Configuration,vc2010后可以选择All Configuration了。

图1.13

1.9 编译前事件

编译前,需要执行"编译前事件"。下图是VC++.NET的配置:

图1.14

上图表示编译前将执行两条命令:

"cd ..\..\..\mpir\build.vc10"表示设置..\..\..\mpir\build.vc10为当前目录。这是相对于W:\mpir\v2.7.0\vc\make-dll-c\vc6\mpir.dsp的目录,换成绝对目录就是W:\mpir\v2.7.0\mpir\build.vc10

"prebuild gc Win32"表示运行当前目录下的prebuild.bat文件,也就是运行W:\mpir\v2.7.0\mpir\build.vc10\prebuild.bat。gc和Win32是传递给prebuild.bat的两个参数。第一个参数有三个选项:gc、p3、core2,分别表示不使用汇编代码、使用32位汇编代码、使用64位汇编代码。第二个参数有两个选项:Win32、x64,分别表示32位、64位平台。

VC++6.0不支持"编译前事件",可以设置gmp-h.in文件的Custom Build,如下图所示:

图1.15

编译时,只要gmp-h.in是第一个被编译的,那么"cd ..\..\..\mpir\build.vc10"和"prebuild gc Win32"就会被执行,相当于"编译前事件"。

prebuild.bat的内容有些复杂,笔者并没有完全理解,只知道"prebuild.bat gc Win32"执行后将在W:\mpir\v2.7.0\mpir目录下生成五个文件:config.h、gmp.h、gmp-mparam.h、longlong.h、mpir.h。这些都是编译时需要的文件。

1.10 修改 obj 的位置

mpf、mpn、mpq、mpz下有很多重名的.c文件,编译时它们将生成重名的.obj文件。这些重名的.obj文件不能放在同一目录下,因此需要修改mpf、mpn、mpq、mpz这四个目录下所有.c文件生成的.obj文件的存放目录。

对于VC++6.0,设置如下图所示。mpf目录下的.c文件生成的.obj文件,原存放目录为 Temp\DU,现存放目录为Temp\DU\mpf。

图1.16

对于VC++.NET,设置如下图所示。mpf目录下的.c文件生成的.obj文件,原存放目录为$(IntDir)\,现存放目录为$(IntDir)\mpf\。注意:$(IntDir)\mpf\最后的\一定不能少,因为$(IntDir)\mpf会被当做文件,而$(IntDir)\mpf\才会被当做目录。

图1.17

根据上面两张图的配置,再修改mpn、mpq、mpz目录下.c文件的配置。

1.11 编译yasm

不需要编译汇编代码的,请跳过本节。

编译汇编代码需要yasm。mpir 2.7.0自带了yasm源代码,如下所示:

W:\mpir\v2.7.0\mpir\yasm\Mkfiles\vc9\yasm.sln            使用vc2008编译

W:\mpir\v2.7.0\mpir\yasm\Mkfiles\vc10\yasm.sln            使用vc2010编译

如果需要最新版本的yasm,可到如下网址下载:

http://www.tortall.net/projects/yasm/

http://yasm.tortall.net/

使用vc2010打开W:\mpir\v2.7.0\mpir\yasm\Mkfiles\vc10\yasm.sln。选择Win32 Release,然后鼠标右键单击"vsyasm"在弹出菜单中单击【Rebuild】。如下图所示。

编译时将会执行Python脚本文件W:\mpir\v2.7.0\mpir\yasm\modules\arch\x86\gen_x86_insn.py。笔者不清楚该脚本做了哪些工作,经测试发现不执行该脚本也不会影响最终exe文件的生成。

图1.18

编译生成的文件是W:\mpir\v2.7.0\mpir\yasm\Mkfiles\vc10\Win32\Release\vsyasm.exe。VC++可以调用该程序编译汇编代码。

1.12 编译汇编代码

不需要编译汇编代码的,请跳过本节。

VC++调用yasm编译汇编代码有三种方法:Custom Build、.rules文件、.targets文件。

1.12.1 Custom Build

Custom Build的优点是适用面广,vc6~vc2015都能使用;缺点是修改命令行参数稍显麻烦。

下图是mpn\yasm\*.asm的Custom Build配置:

图1.19

Outputs是编译*.asm后的输出文件,连接时会用到此文件。上图的设置为"$(IntDir)\$(InputName).obj"其中$(IntDir)是编译时的临时目录,$(InputName)是编译.asm文件名,如:编译add_n.asm时,$(InputName)就是add_n。

Commands是vsyasm.exe的命令行,具体如下:

..\..\..\mpir\yasm\Mkfiles\vc10\Win32\Release\vsyasm.exe -Xvc -f Win32 -g cv8 -d "DLL" -o "$(IntDir)\\" -rnasm -pnasm $(InputPath)

..\..\..\mpir\yasm\Mkfiles\vc10\Win32\Release\vsyasm.exe是W:\mpir\v2.7.0\mpir\yasm\Mkfiles\vc10\Win32\Release\vsyasm.exe相对于W:\mpir\v2.7.0\vc\make-dll-asm32\vc6\mpir.dsp的相对路径。

-Xvc 是错误信息显示格式。对于gcc编译器可设置为 -Xgcc 或 -Xgnu。

-f Win32 表明是32位平台,对于64位平台可指定为-f x64

-g cv8 用来生成调试信息,这种调试信息不能被 vc6 识别,所以使用vc6编译.asm文件时,请去除该选项。

-o "$(IntDir)\\"表示将在目录$(IntDir)里生成.obj文件。注意$(IntDir)后面的两个反斜杠一个都不能少。

$(InputPath)表示输入文件,如:add_n.asm、addmul_1.asm……

这里需要说明一下vc6里Custom Build的编译顺序。因为vc6不支持"编译前事件",可使用Custom Build代替"编译前事件",此时编译顺序就显得非常重要了。笔者经实验得到以下规律(并不能确保它一定正确):

1、Custom Build比.c或.cpp的编译要早;

2、在IDE里先后设置文件A、B的Custom Build,则编译时的顺序为逆序,即先编译B再编译A;

3、初次打开.dsp文件,编译顺序是文件在.dsp里的相反顺序。如:.dsp文件里从上到下依次有A、B需要Custom Build,那么编译时先编译B再编译A。

在图1.15中,gmp-h.in在.dsp文件里是最后一个文件,因此Custom Build时它总是第一个被编译。这样,就保证了它扮演"编译前事件"的角色。

1.12.2 .rules文件

vc2005和vc2008可以使用. rules文件。使用vc2008打开W:\mpir\v2.7.0\vc\make-dll-asm32\vc2008\mpir.sln,鼠标右键单击mpir项目,弹出菜单中单击【Custom Build Rules...】菜单项

图1.20

弹出如下界面,请单击"Find Existing..."按钮。

图1.21

请载入W:\mpir\v2.7.0\mpir\yasm\Mkfiles\vc9\yasm.rules文件,如下图所示:

图1.22

下图所示界面,请单击"否"按钮。

图1.23

下图所示界面内,请勾选"Yasm",然后单击"OK"按钮。

图1.24

此时查看mpir项目属性,可以看到配置里多了一项"Yasm Assembler",可以在这里对Yasm的命令行参数进行配置。如下图所示:

图1.25

再查看某个.asm文件的属性,可以看到它被自动关联到Yasm Assembler,也就是说编译.asm文件时将使用Yasm Assembler来编译。如下图所示:

图1.26

1.12.3 .targets文件

从vc2010开始. rules文件被.targets文件代替。使用vc2010打开W:\mpir\v2.7.0\vc\make-dll-asm32\vc2010\mpir.sln,鼠标右键单击mpir项目,弹出菜单中单击【Build Customization...】菜单项

图1.27

同样是单击"Find Existing..."按钮

图1.28

请载入W:\mpir\v2.7.0\mpir\yasm\Mkfiles\vc10\vsyasm.targets文件,如下图所示:

图1.29

下图所示界面,请单击"否"按钮。

图1.30

下图所示界面内,请勾选"vsyasm",然后单击"OK"按钮。

图1.31

注意:Yasm Assembler不会自动关联*.asm,需要将*.asm的Item Type属性更改为Yasm Assembler。

图1.32

1.13 替换long long

VC++6.0不支持long long,可用__int64替换它。具体如下:

1、替换 gmp-impl.h 里的 long long int 为 __int64;

修改后的两行代码如下:

typedef    __int64 DItype;

typedef unsigned __int64 UDItype;

2、替换printf\doprnt.c、printf\repl-vsnprintf.c、scanf\doscan.c里的long long 为 __int64。

1.14 strnlen函数

vc6、vc2002、vc2003不支持strnlen函数,所以需要修改代码。具体就是修改printf\repl-vsnprintf.c

修改前

修改后

#if ! HAVE_STRNLEN

static size_t

strnlen (const char *s, size_t n)

{

size_t i;

for (i = 0; i < n; i++)

if (s[i] == '\0')

break;

return i;

}

#endif

#if _MSC_VER <= 1310

static size_t strnlen(const char*str

,size_t num)

{

size_t n = 0;

if(str && num)

{

while(str[n])

{

if(++n >= num)

{

break;

}

}

}

return n;

}

#endif//#if _MSC_VER <= 1310

vc6、vc2002、vc2003的_MSC_VER分别为1200、1300、1310。从vc2005开始,VC++实现了strnlen函数。

转载于:https://www.cnblogs.com/endv/articles/7030365.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/370300.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

导弹拦截

链接 分析&#xff1a;经典DP题&#xff0c;最长不下降子序列的变种&#xff0c;同时需要记录路径&#xff0c;用pre[]数组记录当前结点的前一个结点的方法很妙 1 #include "iostream"2 #include "cstdio"3 #include "cstring"4 #include "…

Spring中的@Cacheable开销

Spring 3.1引入了很棒的缓存抽象层 。 最后&#xff0c;我们可以放弃所有本地化的方面&#xff0c;装饰器和污染我们与缓存相关的业务逻辑的代码。 从那时起&#xff0c;我们可以简单地注释重量级方法&#xff0c;并让Spring和AOP机械完成工作&#xff1a; Cacheable("bo…

电工接线模拟仿真软件_VERICUT数控加工仿真软件,最强的数控加工模拟软件,你知道么?...

VERICUT数控加工仿真软件,最强的数控加工模拟软件VERICUT软件及功能简介1、VERICUT软件简介VERICUT是美国CGTech公司开发一款专业的数控加工仿真软件&#xff0c;是当前全球数控加工程序验证、机床模拟、工艺程序优化软件领域的领导者。该软件自1988年开始推向市场以来&#xf…

php数据库创建文件失败怎么回事,安装zblogPHP提示“创建c_option.php失败”解决方法...

有zblog用户反应在安装zblog的最后一步时提示“创建c_option.php失败”&#xff0c;如下图&#xff1a;本文来说明下这个问题的原因和解决办法。问题产生的原因&#xff1a;c_option.php是zblog的数据库配置文件&#xff0c;当安装完成的时候程序会自动创建这个文件。如果你的主…

CSS Variables

CSS原生变量(CSS自定义属性) 示例地址&#xff1a;https://github.com/ccyinghua/Css-Variables 一、css原生变量的基础用法 变量声明使用两根连词线"--"表示变量&#xff0c;"$color"是属于Sass的语法&#xff0c;"color"是属于Less的语法&a…

【基础中的基础】引用类型和值类型,以及引用传递和值传递

一直在博客园怼人&#xff0c;非常惭愧。所以郑重决定&#xff1a; 好好写一篇干货&#xff0c;然后再接着怼人。 这是一起帮上陈百万同学的求助&#xff0c;讲了一会之后&#xff0c;我觉得很有些普世价值&#xff0c;干脆就发到园子来。面向小白&#xff0c;高手轻拍。 我们从…

Java 7:使用NIO.2进行文件过滤–第3部分

大家好。 这是使用NIO.2系列进行文件过滤的第3部分。 对于那些尚未阅读第1 部分或第2部分的人 &#xff0c;这里有个回顾。 NIO.2是自Java 7起JDK中包含的用于I / O操作的新API。使用此新API&#xff0c;您可以执行与java.io相同的操作&#xff0c;以及许多出色的功能&#xf…

Hadoop Serialization -- hadoop序列化具体解释 (2)【Text,BytesWritable,NullWritable】

回想&#xff1a;回想序列化&#xff0c;事实上原书的结构非常清晰&#xff0c;我截图给出书中的章节结构&#xff1a;序列化最基本的&#xff0c;最底层的是实现writable接口&#xff0c;wiritable规定读和写的游戏规则 &#xff08;void write(DataOutput out) throws IOExce…

我需要多少个线程?

这取决于您的应用程序。 但是对于那些希望对如何从生产站点购买的所有昂贵内核中挤出更多资金的人来说&#xff0c;请多多包涵&#xff0c;我将阐明围绕多线程 Java应用程序的奥秘。 内容针对最典型的Java EE应用程序进行了“优化”&#xff0c;该应用程序具有Web前端&#xff…

H5网页适配 iPhoneX,就是这么简单

iPhoneX 取消了物理按键&#xff0c;改成底部小黑条&#xff0c;这一改动导致网页出现了比较尴尬的屏幕适配问题。对于网页而言&#xff0c;顶部&#xff08;刘海部位&#xff09;的适配问题浏览器已经做了处理&#xff0c;所以我们只需要关注底部与小黑条的适配问题即可&#…

数字校园-云资源平台 2014.10.26-人人通共享空间

近期,教育部在统计学校信息化建设情况,当中一项重要内容,作为三通两平台的一个环节,就是学校开通人人通空间的情况,网上普及了一下知识,不就是十多年前就玩的学校博客的变种吗,网上有一些产品,也是没有热闹起来,为要求而要求的多,既然要求,就来一个吧,花了几天时间,也做了一个.…

Lucene –快速添加索引和搜索功能

什么是Lucene&#xff1f; Apache LuceneTM是完全用Java编写的高性能&#xff0c;功能齐全的文本搜索引擎库。 它是一项适用于几乎所有需要全文搜索的应用程序的技术&#xff0c;尤其是跨平台的应用程序。 Lucene可以纯文本&#xff0c;整数&#xff0c;索引PDF&#xff0c;Of…

《深入理解Java虚拟机》读书笔记3--垃圾回收算法

转载&#xff1a;http://blog.csdn.net/tjiyu/article/details/53983064 下面先来了解Java虚拟机垃圾回收的几种常见算法&#xff1a;标记-清除算法、复制算法、标记-整理算法、分代收集算法、火车算法&#xff0c;介绍它们的算法思路&#xff0c;有什么优点和缺点&#xff0c;…

Flex布局(一)flex-direction

采用Flex布局的元素&#xff0c;被称为Flex容器(flex container)&#xff0c;简称"容器"。其所有子元素自动成为容器成员&#xff0c;成为Flex项目(Flex item)&#xff0c;简称"项目" Flex-direction调整主轴方向&#xff08;默认为水平方向&#xff09;包…

登录网页后要弹出一个新标签_连永久链接都不会,还做什么新媒体?

上次给主编大大发的预览链接失效了&#xff0c;被骂得狗血淋头。大部分运营人可能都遇到过这种情况&#xff0c;忽视了预览生成的链接只是临时的&#xff0c;在12小时后或超过500阅读量后就会失效。一个疏忽&#xff0c;给自己带来了不必要的麻烦&#xff0c;耽误工作&#xff…

static_cast与dynamic_cast转换

static_cast与dynamic_cast转换   一 C语言中存在着两种类型转换&#xff1a; 隐式转换和显式转换 隐式转换&#xff1a;不同数据类型之间赋值和运算&#xff0c;函数调用传递参数……编译器完成 char ch;int i ch; 显示转换&#xff1a;在类型前增加 &#xff1a;&#xff…

vue使用iview Timeline 时间轴不显示问题

vue Timeline 时间轴不显示渲染的效果 官网代码 <Timeline pending><TimelineItem>发布1.0版本</TimelineItem><TimelineItem>发布2.0版本</TimelineItem><TimelineItem>发布3.0版本</TimelineItem><TimelineItem><a href…

Java EE 6 Web配置文件。 在云上。 简单。

Java SE还可以。 Java EE是邪恶的。 这就是我一直想的。 好吧&#xff0c;现在不再了。 让我分享我的经验。 几周前&#xff0c;我开始考虑将旧版spring hibernate tomcat应用程序移植到新平台上&#xff1a; SAP NetWeaver云 。 我知道您在极客那里的想法&#xff1a;…

Kubernetes核心概念总结

1、基础架构 1.1 Master Master节点上面主要由四个模块组成&#xff1a;APIServer、scheduler、controller manager、etcd。 APIServer。APIServer负责对外提供RESTful的Kubernetes API服务&#xff0c;它是系统管理指令的统一入口&#xff0c;任何对资源进行增删改查的操作都要…

php连接mysql数据,php连接mysql数据库

$sql_link mysql_connect("主机名","登入用户名","登入用户名密码");如果连接成功&#xff0c;就会返回一个mysql句柄,可以简单的理解成这个$sql_link 是php跟mysql的一个桥梁&#xff0c;通过该桥梁我们可以进入到mysql。进入到mysql之后&…