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,一经查实,立即删除!

相关文章

PHP大数据处理【转】

1&#xff1a;硬件方面 普通的一个p4的服务器每天最多能支持大约10万左右的IP&#xff0c;如果访问量超过10W那么需要专用的服务器才能解决&#xff0c;如果硬件不给力 软件怎么优化都是于事无补的。主要影响服务器的速度 有&#xff1a;网络-硬盘读写速度-内存大小-cpu处理速度…

http1.X与2.0

HTTP HTTP 1.X HTTP是建立在TCP协议上的&#xff0c;HTTP协议的瓶颈及优化都是基于TCP协议本身的特性。TCP建立连接时有三次握手 会有1.5RTT的延迟&#xff0c;为了避免每次请求都经历握手待来的延迟&#xff0c;应用层会选择不同策略的http长连接。 HTTP 1.0 连接不能复用以…

php代码清除空格注解,去除php注释和去除空格函数分享

虽然php5中已有php_strip_whitespace方法可以返回删除注释和空格后的PHP源码的功能&#xff0c;为了学习&#xff0c;这里为大家提供一个自己的方法&#xff0c;也可以去除代码中的空白和注释&#xff0c;代码如下&#xff1a;. 代码如下:/*** 去除代码中的空白和注释* param s…

包装的重要性

我记得大约15年前开始学习Java的时候。 我读了很多有关“包装”和“命名空间”的东西&#xff0c;但我完全不了解。 可悲的是&#xff1a;虽然包装的某些方面几乎为业内每个人所了解&#xff0c;但其他方面却并非如此。 因此&#xff0c;让我们看一下哪些软件包最适合。 命名空…

我的python学习笔记全集_我的python学习笔记

(此文是在实际工程中遇到的一些小问题&#xff0c;给予解决和整理。解决方法大多来自网上零散的文章。)1——如下代码&#xff0c;a[1,2,3]bab也是[1,2,3]了&#xff0c;接着a[0]4a[1]5a[2]6此时a变成[4,5,6]了&#xff0c;再看b&#xff0c;a变了之后没有对b进行新的引用&…

课时28.假链接(掌握)

什么是假链接&#xff1f; 就是点击之后不会跳转的链接我们称之为假链接。 假链接存在的意义&#xff1f; 在企业开发前期&#xff0c;其他界面都没有写出来&#xff0c;那么&#xff0c;我们就不知道应该跳转到什么地方&#xff0c;所以就只能使用假链接来代替&#xff0c;…

笔记45 | 代码性能优化建议[转]

地址 笔记45 | 代码性能优化建议[转] 目录 前言避免创建不必要的对象选择Static而不是Virtual常量声明为Static Final避免内部的Getters/Setters使用增强的For循环使用包级访问而不是内部类的私有访问避免使用float类型使用库函数谨慎使用native函数关于性能的误区前言 通常来说…

导弹拦截

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

JUnit4参数化和理论示例

我始终依靠TestNG将参数传递给测试方法&#xff0c;以便为我的测试或套件提供一些灵活性。 但是&#xff0c;使用JUnit4可以实现相同的灵活性。 要使用它很简单&#xff1a; package com.marco.test;import java.util.Arrays;import java.util.Collection;import junit.fram…

杨杰matlab神经网络30例,MATLAB神经网络30例

实例1 BP神经网络在非线性函数拟合中的应用11.1 理论基础11.1.1 BP网络概述11.1.2 BP神经网络的MATLAB函数21.2 非线性函数拟合方法6实例2 主元BP神经网络在股票价格预测中的应用122.1 理论基础122.1.1 主成分分析的原理122.1.2 主元神经网络与股票预测142.2 股票价格的预测方法…

HTMLCSS 问题

1.子div使用浮动&#xff0c;父div高度自适应(个人感觉好用) 方法&#xff1a; css: <style> .clear{ clear:both} </style> html&#xff1a;在父div关闭之前添加<div class"clear"></div> 本文转载于:猿2048⇛https://www.mk2048.com/…

python matplotlib数据可视化教程_matplotlib的Python数据可视化和探索——入门指南

matplotlib——最受欢迎的Python库&#xff0c;用于数据可视化和探索我喜欢在Python中使用matplotlib。这是我学会掌握的第一个可视化库&#xff0c;此后一直存在。matplotlib是最受欢迎的用于数据可视化和探索的Python库&#xff0c;这是有原因的——它提供的灵活性和敏捷性是…

mysql 查询所有子节点的相关数据

定义一个函数 CREATE DEFINERrootlocalhost FUNCTION getColumnChildLst(rootId INT) RETURNS varchar(1000) CHARSET utf8 BEGINDECLARE sTemp VARCHAR(1000);DECLARE sTempChd VARCHAR(1000);SET sTemp $;SET sTempChd cast(rootId as CHAR);WHILE sTempChd is not null DOS…

怎么用PHP实现年月日date,PHP date函数用法,php年月日写法

日期和时间信息在 PHP 内部是以 64 位数字存储的&#xff0c; 它可以覆盖当前时间前后 2920 亿年的时间&#xff0c;这个范围之广&#xff0c;足以满足现有应用的实际需求。需要注意的是&#xff0c; 这些PHP时间函数都是依赖服务器的区域设置的&#xff0c; 所以在使用它们的时…

python气象卫星云图解析_【我教你系列】想要实时的地球图像作为桌面?

Python 定时获取卫星图像做为桌面背景简介这两天看新闻的时候&#xff0c;突然发现最近有个台风产生&#xff0c;并且在不断的增强中。幸运的是从中央气象台预报的路径来看&#xff0c;不会登陆我国。也正是通过这则新闻&#xff0c;我发现了一个不错的卫星云图网站。(ps:这篇文…

CSS权重的比较方法

CSS的权重如下&#xff1a; !important Infinity正无穷 行间样式 1000 id 100 class|属性|唯类 10 标签|伪元素 1 通配符 0 256进制 当出现多个选择器时 在同一行的选择器权重相加即可 当两个混合选择器权重相同时优先选择后面的选择器 如&#xff1a; html <…

python_day8 面向对象常用 补充

__str__ 作用本来 打印 类对象是 打印的内存地址 但是在类中 增加 __str__ 参数 以后 再打印这个 类对象 就是显示 __str__中的 return __del__作用 当 实例化的对象 在内存中 被释放的时候执行 item操作通过 set get del 操作 item最终目的是将 类里面的 变量 像 字典一样操作…

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;当安装完成的时候程序会自动创建这个文件。如果你的主…