Visual Stdio 环境下使用 GSL (GNU Scientific Library)

时间:2022-09-11 15:36:07

Visual Stdio 环境下使用 GSL (GNU Scientific Library)

经測试。这里的方法不适用于VS2015。

* 这篇文章有点过时了。建议从以下网址下载能够在 vs 环境下编译的 GSL:*

https://github.com/BrianGladman/gsl

GNU Scientific Library (GSL)是一个开源的科学计算的函数库,功能非常强大。

网上介绍它的文章非常多,并且 GSL 的文档也写的非常的好,属于那种特别easy上手的函数库。

这里就不多对 GSL 进行介绍了。

今天要讲的是怎样在 Visual stdio 环境下使用这个库。事实上这方面的内容网上也有一些。只是採用的方法大多不太好。

有的是直接下载 GSL for Widows 来使用,可是这个 GSL for Widows 是 2006 年的GSL 1.8 ,古董级的版本号了,这个版本号缺少的功能太多。

还有一种方法是改造 MinGW 编译的生成的 dll。

事实上不同的 C 语言编译器编译生成的 dll 仅仅要遵守同样的 C calling Conven,原则上是能够通用的。可是不同的编译器自带的库函数是有区别的。

比方说 GSL 库中代码常常会用到 hypot 函数,这个函数在 MinGW 工具链中属于标准数学库中的函数。能够直接使用。可是 Visual stdio 的数学库中却没有这个函数。因此,直接拿来用 MinGW 的 gsl 是不行的,会在 link 阶段遇到缺少各种函数的定义的问题。

因此,假设想要在 Visual Stdio 环境下使用 GSL 最好的办法是又一次编译 GSL 代码。简单说这又分成了两个不同的道路。

  • 使用 Visual Stdio 中的 C 编译器编译 GSL
  • 使用 MinGW 中的 C 编译器编译 GSL

当中第一种方法相对来说麻烦些。须要建立个 Visual Stdio project。将相关的代码加入到project中,还须要改动个别几处 gsl 的代码(主要是由于 Visual Stdio 的 C 编译器不支持 C99 标准中的 inline 特性,GSL 代码中有几处不够严谨没有考虑这个问题)。

另外就是 Visual Stdio 的编译器生成 DLL 须要通过 def 文件来指定导出函数,这个 def 文件须要我们自己来生成。gsl 的源码中没有给出。由于这样的方法比較繁琐,对新手来说失败的可能性非常大,因此我今天主要介绍还有一种方法。

使用 MinGW 中的 C 编译器编译 GSL

熟悉 Linux 下软件编译的同学肯定都知道这样的源码编译安装都是标准的三个步骤:

  • ./configure
  • make
  • make install

我们编译 GSL 自然也摆脱不了这个工序。

当然在这之前我们须要有 MinGW 工具链和 MSYS 环境。

在这里我建议大家使用 MSYS2,关于 MSYS2 的安装。能够參考我写的一篇短文:

http://blog.csdn.net/liyuanbhu/article/details/39397931

在工具链准备齐全之后。将 gsl-1.16.tar.gz 解压缩到 MSYS2 的home 文件夹中。之后就是 ./configure 。

这个过程会比較长。可能要用 3、5分钟。

之后在 gsl-1.16 的根文件夹下就会有 config.h 文件了。

对这个文件我们还须要改造一番。之所以要改造是由于这个文件是为 MinGW gcc 工具链准备的,对 Visual Stdio 开发工具来说不是那么适合。

以下就具体的说说这个 config.h 文件的内容。

config.h 的开头 25 行是这样的。

/* config.h.  Generated from config.h.in by configure.  */
/* config.h.in. Generated from configure.ac by autoheader. */ /* Disable deprecated functions and enums while building */
#define GSL_DISABLE_DEPRECATED 1 /* Define if you have inline with C99 behavior */
#define HAVE_C99_INLINE 1 /* Define to 1 if you have the declaration of `acosh', and to 0 if you don't.
*/
#define HAVE_DECL_ACOSH 1 /* Define to 1 if you have the declaration of `asinh', and to 0 if you don't.
*/
#define HAVE_DECL_ASINH 1 /* Define to 1 if you have the declaration of `atanh', and to 0 if you don't.
*/
#define HAVE_DECL_ATANH 1 /* Define to 1 if you have the declaration of `expm1', and to 0 if you don't.
*/
#define HAVE_DECL_EXPM1 1

#define HAVE_C99_INLINE 1 表明编译器支持 C99。尽管 VS 编译器不支持 C99 ,可是这句我们仍然能够保留。 由于 GSL 实际上仅仅是使用到了 C99 的 inline ,其它的特性都没用到。 而 VS 编译器实际上也是支持 inline 的。关于这个 inline 的支持,我们后面还会具体的说。

acosh、asinh、atanh、expm1 这四个函数 VS 的标准库中都是不支持的。

所以要将这四个 1 都改动成 0。

喜欢刨根问底的同学可能会问。VS 中缺少这些函数。会不会影响到 gsl 的功能呢。答案当然是否定的。这些不属于 C 语言标准的函数 GSL 都自己实现了一遍。有些放到了 sys 子文件夹中,有些放到了 utils 文件夹中,还有些分散到其它文件夹。

可是 GSL 实现都在函数名前加了 gsl 前缀。比方 expm1 函数,在 gsl 中实现为:

double gsl_expm1 (const double x)

假设 config.h 中配置为:

#define HAVE_DECL_EXPM1 0

则在 gsl 中全部用的 expm1 函数的地方都会调用 gsl_expm1 函数。

其它须要更改的地方还包含:

#define HAVE_DECL_FINITE 0
#define HAVE_DECL_FREXP 0
#define HAVE_DECL_HYPOT 0
#define HAVE_DECL_ISFINITE 0
#define HAVE_DECL_ISINF 0
#define HAVE_DECL_ISNAN 0
#define HAVE_DECL_LDEXP 0
#define HAVE_DECL_LOG1P 0
#define HAVE_IEEEFP_H 0
#define HAVE_IEEE_DENORMALS 0
#define HAVE_STRDUP 0
#define HAVE_STRINGS_H 0
#define HAVE_UNISTD_H 0

当中 hypot 函数实际上是有的。可是依照 微软的说法:

This POSIX function is deprecated beginning in Visual C++ 2005.

所以我们还是应该不用它。

有了 config.h 文件后我们就能够进行下一步了。

  • make

之后是漫长的等待。编译完毕之后我们须要的文件就都有了。

gsl-1.16\cblas.libs 文件夹中能够找到例如以下文件:

  • libgslcblas.a
  • libgslcblas.dll.a
  • libgslcblas-0.dll

gsl-1.16.libs 文件夹中能够找到例如以下文件:

  • libgsl.a
  • libgsl.dll.a
  • libgsl-0.dll

将这些文件都拷贝出来。 .a 文件改名为 .lib。

头文件在 gsl-1.16\gsl 文件夹中,能够将这个文件夹完整拷贝出来。

我们能够建立一个文件夹,名为 gsl-1.16-vs。

然后建立三个子文件夹,各自是 :

  • include
  • lib
  • bin

将头文件所在的 gsl 文件夹拷贝的 include 文件夹中, .lib 文件复制到 lib 文件夹中,.dll 文件复制到 bin 文件夹中。

至此,我们的工作就完毕了大半了。

大家能够试试我们生成的 lib 文件和 dll 文件。具体怎样在 VS 中使用第三方的库。网上介绍文章有非常多,我就不多说了。

gsl 帮助文件里的第一个样例:

#include <stdio.h>
#include <gsl/gsl_sf_bessel.h>
int main(int argc, char *argv[])
{
double x = 5.0;
double y = gsl_sf_bessel_J0 (x);
printf ("J0(%g) = %.18e\n", x, y);
return 0;
}

这个样例如今能够编译通过并顺利的运行了,得到的结果也是正确的。

可是这时我们还不能高兴太早。 Visual Stdio 还给我们预备了一个大坑等着我们往里跳呢。这个大坑就是 VS 编译器不支持 C99。当然也包含不支持 C99 的 inline。

所以在编译以下的代码时就会报很多错误。

#define HAVE_INLINE 1
#include "stdafx.h"
#include <stdio.h>
#include <gsl/gsl_vector.h> int _tmain(int argc, _TCHAR* argv[])
{
int i;
gsl_vector * v = gsl_vector_alloc (10);
for (i = 0; i < 10; i++)
{
gsl_vector_set (v, i, 1.23 + i);
}
for (i = 0; i < 10; i++)
{
printf ("v_%d = %g\n", i, gsl_vector_get (v, i));
}
gsl_vector_free (v);
getchar();
return 0;
}

报的错误主要是:

error C2054: 在“inline”之后应输入“(”

解决问题就要改动 gsl_inline.h 这个文件。这个文件有例如以下几行。

#ifdef HAVE_INLINE
# if defined(__GNUC_STDC_INLINE__) || defined(GSL_C99_INLINE) || defined(HAVE_C99_INLINE)
# define INLINE_DECL inline /* use C99 inline */
# define INLINE_FUN inline
# else
# define INLINE_DECL /* use GNU extern inline */
# define INLINE_FUN extern inline
# endif
#else
# define INLINE_DECL /* */
#endif

将其改动为 :

#ifdef HAVE_INLINE
# if defined(__GNUC_STDC_INLINE__) || defined(GSL_C99_INLINE) || defined(HAVE_C99_INLINE)
# define INLINE_DECL inline /* use C99 inline */
# define INLINE_FUN inline
# else
# define INLINE_DECL /* use GNU extern inline */
# define INLINE_FUN __inline
# endif
#else
# define INLINE_DECL /* */
#endif

这样再编译就没有错误了。

我将编译好gsl放到了以下的链接里,有须要能够直接下载。

http://download.csdn.net/detail/liyuanbhu/9009755

Visual Stdio 环境下使用 GSL (GNU Scientific Library)的更多相关文章

  1. 【C&plus;&plus;】GSL&lpar;GNU Scientific Library&rpar; 的安装及在 Visual Studio 2017 中的使用

    GSL 是 GNU 开发并维护的科学计算的库,其中包括: 复数 多项式的根 特殊函数 向量和矩阵 排列 排序 BLAS支持 线性代数 Eigensystems 快速傅立叶变换 正交 随机数 准随机序列 ...

  2. (转载)Ubuntu 安装GNU Scientific library(GSL)

    背景: Blei的hlda的C语言实现需要使用C语言的科学计算包GSL,因此决定安装.由于在windows下安装极其繁琐,先在Linux上安装之. 系统环境: Linux version 2.6.35 ...

  3. Ubuntu 安装GNU Scientific library(GSL)

    注: 此系列为自己之前所搭建网站内容. 由于论文数据处理的需要,需要使用libeemd这个包,需要安装gsl科学库,windows下没有办法,只能转战ubuntu进行科学计算. GSL(GNU Sci ...

  4. GNU scientific library

    GNU scientific library 是一个强大的C,C++数学库.它涉及的面很广,并且代码效率高,接口丰富.正好最近做的一个项目中用到多元高斯分布,就找到了这个库. GNU scientif ...

  5. Visual Studio2008环境下查找C&num;中方法的&OpenCurlyDoubleQuote;查看所有引用”

    在Visual Studio开发环境下,想必F12我们都很熟悉了,有没有用过“查看所有引用”呢? 尤其是在一个解决方案中,包含了很多项目,彼此相互的调用是很常见的,例如三层架构, BLL调用DAL,D ...

  6. ubuntu14&period;04 下安装 gsl 科学计算库

    GSL(GNU Scientific Library)作为三大科学计算库之一,除了涵盖基本的线性代数,微分方程,积分,随机数,组合数,方程求根,多项式求根,排序等,还有模拟退火,快速傅里叶变换,小波, ...

  7. 如何使用SOIL在VS2012的 C&plus;&plus;环境下显示图片

    先看下效果. 这是一个很无聊的功能....首先说下,我做这个功能的初衷并不是为了实现在控制台中显示图片...(这貌似很无聊) 而是因为自己想做用C做一个游戏:http://q.cnblogs.com/ ...

  8. GSL--GNU Scientific Library 小记

    摘自http://qianjigui.iteye.com/blog/847612 GSL(GNU Scientific Library)是一个 C 写成的用于科学计算的库,下面是一些相关的包 Desi ...

  9. WIN7环境下CUDA7&period;5的安装、配置和测试(Visual Studio 2010)

    以下基于"WIN7(64位)+Visual Studio 2010+CUDA7.5". 系统:WIN7,64位 开发平台:Visual Studio 2010 显卡:NVIDIA ...

随机推荐

  1. spring源码学习之路---深入AOP(终)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ...

  2. Delphi的基于接口&lpar;IInterface&rpar;的多播监听器模式(观察者模式 )

    本文来自:http://www.cnblogs.com/hezihang/p/6083555.html Delphi采用接口方式设计模块,可以降低模块之间的耦合,便于扩展和维护.本文提供一个实现基于接 ...

  3. Oracle Insert 多行(转)

    1.一般的insert 操作. 使用语法insert into table_name[(column[,column...])] values (value[,value…])的insert语句,每条 ...

  4. python 基础,包括列表,元组,字典,字符串,set集合,while循环,for循环,运算符。

         1.continue 的作用:跳出一次循环,进行下一次循环      2.break 跳出不再循环      3.常量 (全是大写)NAME = cjk  一般改了会出错      4.py ...

  5. JQuery实战总结二 横向纵向菜单下拉效果图

    记得以前在浏览了大多数网站的上面发现很多下拉的导航栏,觉得特别好玩,毕竟咱们是学习编程的嘛,对这下拉的效果还是挺感兴趣的,这种淡入淡出,随着鼠标移动的位置不同.有无等而出现不同的效果,给用户以神美感. ...

  6. Python多线程中阻塞&lpar;join&rpar;与锁&lpar;Lock&rpar;的使用误区

    参考资料:https://blog.csdn.net/cd_xuyue/article/details/52052893 1使用两个循环分别处理start和join函数.即可实现并发. threads ...

  7. hdu 3183 A Magic Lamp(RMQ)

    A Magic Lamp                                                                               Time Limi ...

  8. React-Native 之 index&period;android&period;bundle

    问题: index.android.bundle  这个bug 我相信很少同学会遇到,然而就是这个问题,困扰了我跟我的同事多天, 各种方法处理:  进入 android 目录  ./gradlew c ...

  9. express入门学习&lpar;一&rpar;

    一.安装express cnpm || npm  install express --save ; 1. Hello  World var express = require('express'); ...

  10. Oracle动态执行表不可访问解决方法

    在scott 用户下,执行查询语句是出现“Oracle动态执行表不可访问” 经查,是因为用户权限不够所致,修改scott用户权限语句如下: grant select on V_$session to ...