visualstdio环境下使用gsl(gnuscientificlibrary)

zhchoutai zhchoutai     2022-09-08     293

关键词:

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.16cblas.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.16gsl 文件夹中,能够将这个文件夹完整拷贝出来。

我们能够建立一个文件夹,名为 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
", 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
", 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

论文阅读笔记《groundedactiontransformationforrobotlearninginsimulation》

...接地模拟学习(GroundedSimulationLearning,GSL)框架:使用从现实环境中搜集的轨迹优化模拟环境,再使用优化后的模拟环境训练策略。该框架假设模拟器是可修改的。GSL算法包含以下步骤:在模拟环境中使用强化学习算法训练一个控制... 查看详情

使用回调将 C 库 (GSL) 包装在 cython 代码中

】使用回调将C库(GSL)包装在cython代码中【英文标题】:wrappingaClibrary(GSL)inacythoncodebyusingcallback【发布时间】:2014-07-0114:49:28【问题描述】:我是cython和c的新手。我想使用cython来加快我的代码的性能。我想在我的代码中使用gsl_integ... 查看详情

visualstdio2015打包安装项目的方法(使用visualstudioinstaller)

首先在官网下载VS2015的VisualStudioInstaller1.创建安装项目 里面最左侧的框框有三个文件夹1.“应用程序文件夹”即"ApplicationFolder"表示要安装的应用程序需要添加的文件;2.“用户的‘程序’菜单”即"User‘sProgramsMenu"表示:应用... 查看详情

如何在 nvidia Nsight eclipse 中使用 GNU 科学库 (gsl)

】如何在nvidiaNsighteclipse中使用GNU科学库(gsl)【英文标题】:HowtousetheGNUscientificlibrary(gsl)innvidiaNsighteclipse【发布时间】:2014-03-1009:13:44【问题描述】:我想在我的CUDA代码中使用一些gsl函数。(在linux上的Nsighteclipse中)我已经安装... 查看详情

visualstdio2010格式化代码快捷键使用无效,我用的是ctrl+e,d----格式化全部代码,老说:组合键不可用。

visualstdio2010格式化代码快捷键使用无效,我用的是Ctrl+E,D----格式化全部代码,老说:组合键(Ctrl+E、D)绑定到的命令(FormatDocument)当前不可用。组合键(Ctrl+E,F----格式化选中的代码)也同样无效啊!当时我在编辑C语言工程。... 查看详情

windows系统编译gsl2.7用于c语言编程(2022.5.8)(代码片段)

...8)1、GSL(GNUScientificLibrary)1.1GSL简介1.2前人在Windows平台下已编译好的GSL库(版本太低)2、Windows下利用MSYS2编译GSL库2.1MSYS2简介2.2Windows系统安装MSYS22.3下载GSL源码进行编译构建3、基于GSL库编写C语言代码(CodeBlocks/VisualStudio)3.1在... 查看详情

windows系统编译gsl2.7用于c语言编程(2022.5.8)(代码片段)

...8)1、GSL(GNUScientificLibrary)1.1GSL简介1.2前人在Windows平台下已编译好的GSL库(版本太低)2、Windows下利用MSYS2编译GSL库2.1MSYS2简介2.2Windows系统安装MSYS22.3下载GSL源码进行编译构建3、基于GSL库编写C语言代码(CodeBlocks/VisualStudio)3.1在... 查看详情

ubuntu系统下,gsl库链接问题-undefinedreferenceto`cblas_xxx`

  今天在ubuntu系统下进行程序调试的时候出现以下错误信息:[10%]LinkingCXXexecutable../test_coco/usr/local/lib/libgsl.so:undefinedreferenceto`cblas_ztrsv‘/usr/local/lib/libgsl.so:undefinedreferenceto`cblas_scasum‘/usr/local/lib 查看详情

使用 C++(和 GSL)扩展和嵌入 Python(和 NumPy):将 gsl_matrix 传递给 python 并返回

】使用C++(和GSL)扩展和嵌入Python(和NumPy):将gsl_matrix传递给python并返回【英文标题】:ExtendandEmbedPython(andNumPy)withC++(andGSL):passgsl_matrixtopythonandback【发布时间】:2013-09-1118:40:01【问题描述】:我的问题“应该”很简单,但我仍... 查看详情

visualstdio开发activex控件基本教程

比较少人会专门开发控件,但是有时候工作需要,需要开发简单的控件,控件技术因为要和浏览器交互,所以有些需要注意的点,此文为需要开发简单控件准备,基本满足基本的功能要求。包含必要的工程设置,方法的创建和调... 查看详情

visualstdio2005如何像vc++6.0一样编译和调试啊

换了编程环境,可是不会用,那位能举个从创建cpp文件到编译,调试的例子啊!参考技术A启动“工具”->“导入导出设置”向导,选择“重置所有设置”,在“选择一个默认设置集”中选择“VisualC++开发设置”,点击“完成”... 查看详情

在 CMakeLists.txt 中链接 GSL

...909:41:28【问题描述】:我有一个包含多个文件的代码,它使用GSL库。当我通过终端使用命令编译代码时g++main.cpp-lm-lgsl-lgslcblas-oExec这会编译并给出正确的输出并且没有错误。但是,当我尝试在CLion中构建代码时,出现错误undefinedre... 查看详情

jchdl-gsl-实例-使用intellijidea创建mux

https://docs.qq.com/doc/DR2VaWXNxVFFEb3dw https://github.com/wjcdx/jchdl/blob/master/src/org/jchdl/model/gsl/operator/conditional/Mux.java ?? Mux根据选择位的值,从两位数据中选择一位输出。下面基于IntelljIDEA创建Mu 查看详情

gsl 多变量数值积分

...ion【发布时间】:2018-12-2405:18:07【问题描述】:我一直在使用GSL集成包(gsl_integration.h)来尝试在某个限制[a,b]之间相对于x集成一些多变量函数f(x,y,z)。在这个例子中,我有一个玩具模型:f(x,y,z)=xyz我想用一个函数输出这个积分的结... 查看详情

jchdl-gsl实例-mux4(使用mux)

https://mp.weixin.qq.com/s/GrYJ4KXEFRoLLmLnAGoMSA 原理图?? 参考链接https://github.com/wjcdx/jchdl/blob/master/src/org/jchdl/model/gsl/example/Mux4.java  1.创建Mux4.java,并生成构造方法和logic()方法??& 查看详情

eclipseforc++无法识别自酿的gsl和boost库(代码片段)

我在运行MacOSX的系统上。我使用EclipseOxygen.2forC/C++,在我的例子中是C++。我正在尝试创建一个使用GSL和Boost库的项目。但是,Eclipse似乎无法找到GSL库并且似乎无法识别Boost库,但似乎无法执行Boost库中包含的任何操作。两个库都使... 查看详情

当索引不是整数常量表达式时,不要使用数组下标;改用 gsl::at()

】当索引不是整数常量表达式时,不要使用数组下标;改用gsl::at()【英文标题】:Donotusearraysubscriptwhentheindexisnotanintegerconstantexpression;usegsl::at()instead【发布时间】:2019-01-2412:13:03【问题描述】:我试图在MicrosoftVisualStudio中创建一... 查看详情

gsl_rng_default 未解决的外部错误

...rnalError【发布时间】:2013-05-2419:33:31【问题描述】:尝试使用GSL在Windows上的C语言中生成beta分布的随机偏差。程序不会链接,给出众所周知的“错误LNK2001:无法解析的外部符号_gsl_rng_default”错误消息。问题是不是GSL的常规安装... 查看详情