- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在写Fortran 和C 接口(interface),但总是出现错误。我不确定为什么会出现问题。原始C代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_multiroots.h>
void gsl_vector_setvalue(gsl_vector* v, size_t index, double value)
{
gsl_vector_set(v, index-1, value);
}
double gsl_vector_getvalue(gsl_vector* v, size_t index)
{
return gsl_vector_get(v, index-1);
}
int rosenbrock_f (const gsl_vector * x, void * params, gsl_vector * f)
{
double x0 = gsl_vector_get (x, 0);
double x1 = gsl_vector_get (x, 1);
double y0 = 1. * (1 - x0);
double y1 = 10. * (x1 - x0 * x0);
gsl_vector_set (f, 0, y0);
gsl_vector_set (f, 1, y1);
return GSL_SUCCESS;
}
int print_state (size_t iter, gsl_multiroot_fsolver * s)
{
printf ("iter = %3zu x = % .3f % .3f " "f(x) = % .3e % .3e\n", iter, gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1), gsl_vector_get (s->f, 0), gsl_vector_get (s->f, 1));
}
void gsl_multiroots(int rosenbrock())
{
const gsl_multiroot_fsolver_type *T;
gsl_multiroot_fsolver *s;
int status;
size_t i, iter = 0;
const size_t n = 2;
//struct rparams p = {1.0, 10.0};
struct rparams *p=NULL;
gsl_multiroot_function f = {rosenbrock, n, p};
double x_init[2] = {-10.0, -5.0};
gsl_vector *x = gsl_vector_alloc (n);
gsl_vector_set (x, 0, x_init[0]);
gsl_vector_set (x, 1, x_init[1]);
T = gsl_multiroot_fsolver_hybrids;
s = gsl_multiroot_fsolver_alloc (T, 2);
gsl_multiroot_fsolver_set (s, &f, x);
print_state (iter, s);
do
{
iter++;
status = gsl_multiroot_fsolver_iterate (s);
print_state (iter, s);
if (status) break;
/* check if solver is stuck */
status = gsl_multiroot_test_residual (s->f, 1e-7);
}
while (status == GSL_CONTINUE && iter < 1000);
printf ("status = %s\n", gsl_strerror (status));
gsl_multiroot_fsolver_free (s);
gsl_vector_free (x);
}
int main()
{
gsl_multiroots(rosenbrock_f);
return 0;
}
并且在I编译链接时,可以运行并得到正确的结果。但是当我用 Fortran 代码写 rosenbrock_f 并使用内在模式 iso_c_binding 让它们互操作时,它不能有结果,只能说
> Program received signal SIGSEGV: Segmentation fault - invalid memory
> reference.
>
> Backtrace for this error:
> #0 0x7FCE7F618777
> #1 0x7FCE7F618D7E
> #2 0x7FCE7F270D3F
> #3 0x7FCE7FCF68AD
> #4 0x400BAE in gsl_vector_getvalue
> #5 0x400E45 in rosenbrock.1876 at multiroot.f90:?
> #6 0x7FCE7FC4A923
> #7 0x400D6F in gsl_multiroots
> #8 0x400F0D in MAIN__ at multiroot.f90:? Segmentation fault (core dumped)
这是 C 和 Fortran 代码:
#include <stdlib.h>
#include <stdio.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_multiroots.h>
void gsl_vector_setvalue(gsl_vector* v, size_t index, double value)
{
gsl_vector_set(v, index-1, value);
}
double gsl_vector_getvalue(gsl_vector* v, size_t index)
{
return gsl_vector_get(v, index-1);
}
int print_state (size_t iter, gsl_multiroot_fsolver * s)
{
printf ("iter = %3zu x = % .3f % .3f " "f(x) = % .3e % .3e\n", iter, gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1), gsl_vector_get (s->f, 0), gsl_vector_get (s->f, 1));
}
void gsl_multiroots(int rosenbrock())
{
const gsl_multiroot_fsolver_type *T;
gsl_multiroot_fsolver *s;
int status;
size_t i, iter = 0;
const size_t n = 2;
struct rparams *p=NULL;
gsl_multiroot_function f = {rosenbrock, n, p};
double x_init[2] = {-10.0, -5.0};
gsl_vector *x = gsl_vector_alloc (n);
gsl_vector_set (x, 0, x_init[0]);
gsl_vector_set (x, 1, x_init[1]);
T = gsl_multiroot_fsolver_hybrids;
s = gsl_multiroot_fsolver_alloc (T, 2);
gsl_multiroot_fsolver_set (s, &f, x);
print_state (iter, s);
do
{
iter++;
status = gsl_multiroot_fsolver_iterate (s);
print_state (iter, s);
if (status) break;
/* check if solver is stuck */
status = gsl_multiroot_test_residual (s->f, 1e-7);
}
while (status == GSL_CONTINUE && iter < 1000);
printf ("status = %s\n", gsl_strerror (status));
gsl_multiroot_fsolver_free (s);
gsl_vector_free (x);
}
fortran 模块:
MODULE gsl_interfaces
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
TYPE, BIND(C) :: gsl_block
INTEGER(C_SIZE_T) :: size
TYPE(C_PTR) :: data
END TYPE gsl_block
TYPE, BIND(C) :: gsl_vector
INTEGER(C_SIZE_T) :: size
INTEGER(C_SIZE_T) :: stride
REAL(C_DOUBLE) :: data
TYPE(C_PTR) :: block
INTEGER(C_INT) :: owner
END TYPE gsl_vector
TYPE, BIND(C) :: gsl_matrix
INTEGER(C_SIZE_T) :: size1
INTEGER(C_SIZE_T) :: size2
INTEGER(C_SIZE_T) :: tda
REAL(C_DOUBLE) :: data
TYPE(C_PTR) :: block
INTEGER(C_INT) :: owner
END TYPE gsl_matrix
TYPE, BIND(C) :: rparams
REAL(C_DOUBLE) :: A
real(c_double) :: b
END TYPE
INTERFACE
SUBROUTINE GSL_VECTOR_SETVALUE(V, ROW_INDEX, V_VALUE) BIND(C, NAME='gsl_vector_setvalue')
USE ISO_C_BINDING
import gsl_vector
TYPE(c_ptr), VALUE :: V
INTEGER :: ROW_INDEX
REAL(C_DOUBLE), VALUE :: V_VALUE
END SUBROUTINE GSL_VECTOR_SETVALUE
REAL(C_DOUBLE) FUNCTION GSL_VECTOR_GETVALUE(V, ROW_INDEX) BIND(C, NAME='gsl_vector_getvalue')
USE ISO_C_BINDING
import gsl_vector
TYPE(c_ptr), VALUE :: V
INTEGER :: ROW_INDEX
END FUNCTION GSL_VECTOR_GETVALUE
SUBROUTINE GSL_MULTIROOTS(ROSENBROCK) BIND(C, NAME='gsl_multiroots')
USE ISO_C_BINDING
type(c_funptr), value :: ROSENBROCK
! TYPE(c_ptr), value :: x
END SUBROUTINE
! INTEGER(C_INT) FUNCTION ROSENBROCK(x, params, f) BIND(C, NAME='rosenbrock_f')
! USE ISO_C_BINDING
! import gsl_vector
! IMPORT rparams
! TYPE(gsl_vector), target :: x, f
! TYPE(C_PTR), target :: params
! END FUNCTION ROSENBROCK
END INTERFACE
END MODULE gsl_interfaces
fortran 程序:
PROGRAM MULTIROOT
USE, INTRINSIC :: ISO_C_BINDING
USE GSL_INTERFACES
IMPLICIT NONE
integer(c_int), parameter :: GSL_SUCCESS=0
type(gsl_vector), target :: x, f
CALL GSL_MULTIROOTS(c_funloc(ROSENBROCK))
contains
integer(c_int) function rosenbrock(x, params, f) bind(c)
use iso_c_binding
use gsl_interfaces
type(c_ptr) :: x, f
type(c_ptr) :: params
real(c_double) :: x0, x1, y0, y1
!a=params%a
!b=params%b
x0 = gsl_vector_getvalue (x, 1)
x1 = gsl_vector_getvalue (x, 2)
y0 = 1. * (1 - x0)
y1 = 10. * (x1 - x0 * x0)
call gsl_vector_setvalue (f, 1, y0)
call gsl_vector_setvalue (f, 2, y1)
rosenbrock=GSL_SUCCESS
end function rosenbrock
END PROGRAM
有人能帮帮我吗?不知道为什么会出现内存无效引用。
最佳答案
注意:M. S. B.指出存在一个Fortran wrapper已经用于 GNU 科学图书馆。
以下是适用于我的 gcc 5.2 的内容。
我修改了您的 C 代码以与 gsl documentation 中给出的示例保持一致,因为我不确定,您的功能描述的顺序是否与界面匹配。此外,我更改了函数指针声明以匹配 gsl 的期望。
#include <stdlib.h>
#include <stdio.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_multiroots.h>
void gsl_vector_setvalue(gsl_vector* v, size_t index, double value)
{
gsl_vector_set(v, index-1, value);
}
double gsl_vector_getvalue(gsl_vector* v, size_t index)
{
return gsl_vector_get(v, index-1);
}
int print_state (size_t iter, gsl_multiroot_fsolver * s)
{
printf ("iter = %3zu x = % .3f % .3f " "f(x) = % .3e % .3e\n", iter, gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1), gsl_vector_get (s->f, 0), gsl_vector_get (s->f, 1));
}
void gsl_multiroots(int (*rosenbrock)(gsl_vector *x, void *p, gsl_vector *f))
{
const gsl_multiroot_fsolver_type *T;
gsl_multiroot_fsolver *s;
int status;
size_t i, iter = 0;
const size_t n = 2;
void *p = NULL;
gsl_multiroot_function f;
f.f = rosenbrock;
f.n = n;
f.params = &p;
double x_init[2] = {-10.0, -5.0};
gsl_vector *x = gsl_vector_alloc (n);
gsl_vector_set (x, 0, x_init[0]);
gsl_vector_set (x, 1, x_init[1]);
T = gsl_multiroot_fsolver_hybrids;
s = gsl_multiroot_fsolver_alloc (T, 2);
gsl_multiroot_fsolver_set (s, &f, x);
print_state (iter, s);
do
{
iter++;
status = gsl_multiroot_fsolver_iterate (s);
print_state (iter, s);
if (status) break;
/* check if solver is stuck */
status = gsl_multiroot_test_residual (s->f, 1e-7);
}
while (status == GSL_CONTINUE && iter < 1000);
printf ("status = %s\n", gsl_strerror (status));
gsl_multiroot_fsolver_free (s);
gsl_vector_free (x);
}
在接口(interface)中,我为整数添加了 value 属性,这些整数应该作为按值参数调用:
MODULE gsl_interfaces
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
INTERFACE
SUBROUTINE GSL_VECTOR_SETVALUE(V, ROW_INDEX, V_VALUE) BIND(C, NAME='gsl_vector_setvalue')
USE ISO_C_BINDING
TYPE(c_ptr), VALUE :: V
INTEGER,value :: ROW_INDEX
REAL(C_DOUBLE), VALUE :: V_VALUE
END SUBROUTINE GSL_VECTOR_SETVALUE
REAL(C_DOUBLE) FUNCTION GSL_VECTOR_GETVALUE(V, ROW_INDEX) BIND(C, NAME='gsl_vector_getvalue')
USE ISO_C_BINDING
TYPE(c_ptr), VALUE :: V
INTEGER,value :: ROW_INDEX
END FUNCTION GSL_VECTOR_GETVALUE
SUBROUTINE GSL_MULTIROOTS(ROSENBROCK) BIND(C, NAME='gsl_multiroots')
USE ISO_C_BINDING
type(c_funptr), value :: ROSENBROCK
END SUBROUTINE
END INTERFACE
END MODULE gsl_interfaces
在 rosenbrock 函数中,我为 c_ptr 参数添加了缺失值属性:
PROGRAM MULTIROOT
USE, INTRINSIC :: ISO_C_BINDING
USE GSL_INTERFACES
IMPLICIT NONE
integer(c_int), parameter :: GSL_SUCCESS=0
CALL GSL_MULTIROOTS(c_funloc(ROSENBROCK))
contains
integer(c_int) function rosenbrock(x, params, f) bind(c)
use iso_c_binding
use gsl_interfaces
type(c_ptr),value :: x, f
type(c_ptr),value :: params
real(c_double) :: x0, x1, y0, y1
!a=params%a
!b=params%b
x0 = gsl_vector_getvalue (x, 1)
x1 = gsl_vector_getvalue (x, 2)
y0 = 1. * (1 - x0)
y1 = 10. * (x1 - x0 * x0)
call gsl_vector_setvalue (f, 1, y0)
call gsl_vector_setvalue (f, 2, y1)
rosenbrock=GSL_SUCCESS
end function rosenbrock
END PROGRAM
运行它时,我得到:
iter = 0 x = -10.000 -5.000 f(x) = 1.100e+01 -1.050e+03
iter = 1 x = -10.000 -5.000 f(x) = 1.100e+01 -1.050e+03
iter = 2 x = -3.976 24.827 f(x) = 4.976e+00 9.020e+01
iter = 3 x = -3.976 24.827 f(x) = 4.976e+00 9.020e+01
iter = 4 x = -3.976 24.827 f(x) = 4.976e+00 9.020e+01
iter = 5 x = -1.274 -5.680 f(x) = 2.274e+00 -7.302e+01
iter = 6 x = -1.274 -5.680 f(x) = 2.274e+00 -7.302e+01
iter = 7 x = 0.249 0.298 f(x) = 7.511e-01 2.359e+00
iter = 8 x = 0.249 0.298 f(x) = 7.511e-01 2.359e+00
iter = 9 x = 1.000 0.878 f(x) = -2.653e-10 -1.218e+00
iter = 10 x = 1.000 0.989 f(x) = -2.353e-11 -1.080e-01
iter = 11 x = 1.000 1.000 f(x) = 0.000e+00 0.000e+00
status = success
我希望这对您有所帮助,可以帮助您实现您真正想要实现的目标。如果可能的话,我会远离为 C 结构声明 Fortran 类型。如果您可以只使用 c_ptr 作为调用方的句柄,那应该会少很多痛苦。
关于c - Fortran 和 c 的互操作性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32374612/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!