- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在查看一个稍旧的 Fortran 程序,该程序具有适用于 32 位系统的 C 调用,但会引发警告和对 64 位编译器的担忧。该程序将指向动态分配内存的 C 指针地址存储为 int
,在 Fortran 端共享为 INTEGER
。我担心的是,在 64 位整数系统上,C 指针的转换可能大于可以存储为 int
/INTEGER
的值。我已使用两个文件将现有程序简化为此示例。
this.f
program this
integer,pointer :: iptr
allocate(iptr)
call that_allocate(iptr)
write(*,'(A, Z12)') 'Fortran: iptr address', iptr
call that_assemble(iptr)
call that_free(iptr)
end program this
那个.c
#include <stdlib.h>
#include <stdio.h>
typedef struct data {
int a;
float b;
} data;
void that_allocate_(int* iptr)
{
data *pData = calloc(1, sizeof(data));
*iptr = (int)pData;
printf("C: Allocated address %p (or %d)\n", pData, pData);
return;
}
void that_assemble_(int* iptr)
{
data *pData = (data *) *iptr;
pData->a = 42;
pData->b = 3.1415926;
return;
}
void that_free_(int* iptr)
{
data *pData = (data *) *iptr;
printf("C: Freeing data %d and %g at %p\n", pData->a, pData->b, pData);
free(pData);
return;
}
程序可以使用 GNU 编译器编译,-m32
用于 32 位(这里没有问题),-m64
用于 64 位。编译 C 代码会引发一些警告:
$ gcc -m64 -c that.c
that.c: In function ‘that_allocate_’:
that.c:12: warning: cast from pointer to integer of different size
that.c: In function ‘that_assemble_’:
that.c:19: warning: cast to pointer from integer of different size
that.c: In function ‘that_free_’:
that.c:27: warning: cast to pointer from integer of different size
而其余的编译和链接都很好,并且程序可以运行:
$ gfortran -m64 -o prog this.f that.o
$ ./prog
C: Allocated address 0x1130b40 (or 18025280)
Fortran: iptr address 1130B40
C: Freeing data 42 and 3.14159 at 0x1130b40
虽然我看到 calloc
返回的地址可以容纳在 4 字节整数的数据限制内,但是 calloc
返回一个更大的地址是否存在风险整数?使用 (intptr_t)
进行转换将使编译警告静音,但我怀疑它会截断任何更高的位,如果尝试将指针转换为截断的地址,则会出现“段错误”。这是正确的吗?
我该怎么办?是否需要在 Fortran 代码上进行修复?
最佳答案
是的,存在潜在的位数问题。如果您希望您的代码在面对编译器和平台变化时保持健壮,那么您应该做很多事情,其中大部分都依赖于 Fortran 2003 的 C 互操作性特性。最近的 gfortran 支持这些语言特性和最积极维护的 Fortran 编译器。
从你的例子中不清楚 Fortran 代码是否真的需要知道指向 data
结构的指针的值作为整数(在你的例子中你打印了这个值,但我怀疑仅用于调试)。如果 Fortran 代码只需要将指针视为不透明句柄,那么 ISO_C_BINDING 内部模块中的 C_PTR 类型就相当于 C 指针。如果出于某种原因 Fortran 代码确实需要知道指针的值作为整数,那么 C_INTPTR_T 类型的整数(同样来自 ISO_C_BINDING 内部模块)是合适的。更进一步,如果您希望 Fortran 代码能够处理实际结构本身,那么您可以定义一个 BIND(C) 派生类型并以各种方式使用它。
此外,您的 C 代码假定 Fortran 编译器使用特定的调用约定,包括过程名称被破坏以形成链接器名称的方式。您可以在 Fortran 端的接口(interface) block 中使用 BIND(C,NAME='xxx') 属性来指定 Fortran 编译器使用与其配套 C 编译器兼容的调用约定并指定过程的 C 名称.
请注意,考虑到示例的其余部分,整数上的 POINTER 声明及其后续分配是不相关的。
全部(自由形式,固定形式合适已经有一段时间了):
PROGRAM this
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_INTPTR_T
IMPLICIT NONE
! Interfaces required due to BIND(C). Also allows the Fortran
! compiler to do better error checking. Note that the default
! binding label is a lowercase variant of the Fortran name, but
! we specify it explicitly here anyway for clarity.
INTERFACE
SUBROUTINE that_allocate(the_c_ptr) &
BIND(C,NAME='that_allocate')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
IMPLICIT NONE
! Note passing a pointer by reference.
TYPE(C_PTR), INTENT(OUT) :: the_c_ptr
END SUBROUTINE that_allocate
SUBROUTINE that_assemble(the_c_ptr) &
BIND(C,NAME='that_assemble')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
IMPLICIT NONE
! Note passing a pointer by value.
TYPE(C_PTR), INTENT(IN), VALUE :: the_c_ptr
END SUBROUTINE that_assemble
SUBROUTINE that_free(the_c_ptr) &
BIND(C,NAME='that_free')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
IMPLICIT NONE
! Note passing a pointer by value.
TYPE(C_PTR), INTENT(IN), VALUE :: the_c_ptr
END SUBROUTINE that_free
END INTERFACE
TYPE(C_PTR) :: the_c_ptr
CALL that_allocate(the_c_ptr)
! Use transfer to convert the C address to an integer value.
PRINT "('Fortran: ptr address',Z12)", &
TRANSFER(the_c_ptr, 0_C_INTPTR_T)
CALL that_assemble(the_c_ptr)
CALL that_free(the_c_ptr)
END PROGRAM this
并在 C 端进行简化:
#include <stdlib.h>
#include <stdio.h>
typedef struct data {
int a;
float b;
} data;
void that_allocate(data** pData)
{
*pData = (data*) calloc(1, sizeof(data));
printf("C: Allocated address %p\n", *pData);
return;
}
void that_assemble(data* pData)
{
pData->a = 42;
pData->b = 3.1415926;
return;
}
void that_free(data* pData)
{
printf("C: Freeing data %d and %g at %p\n", pData->a, pData->b, pData);
free(pData);
return;
}
关于c - 将 Fortran/C 程序从 32 位升级到多体系结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15473004/
这个问题在这里已经有了答案: What is an undefined reference/unresolved external symbol error and how do I fix it?
我遇到了这两个文档(它们是用意大利语写的,尽管代码注释是英文的): http://home.deib.polimi.it/brandole/acsocr/L13%20-%20Generic%20Ass
我的主要目标是提供一个用 jquery 编写的基于 solr 的搜索应用程序。 (不熟悉solr的,就假设它是一个可以返回搜索结果的rest api。)为了这个目标,我编写了许多小型应用程序和 ser
这个问题是关于选择“正确”类型的NoSQL数据库的,我希望甚至可以根据我将在下面列出的一些需求/用例以及当前正在使用的传统RDBMS解决方案,讨论特定的数据库以及它们为什么适用。地点。时间长了一点,但
在 Java 中我运行: System.out.println(Math.log(249.0/251.0)); Output: -0.008000042667076265 在 C# 中我运行:<- 已
我目前正在考虑通过 Redux 将 Context 实现到我们的一个应用程序中,但是,我似乎找不到任何关于什么是大型应用程序的最佳结构的信息? Redux 有一个定义的方法来创建 reducer、ac
我正在使用 mailcore 框架,但收到错误消息“archtecture x86 的重复符号”以及“找不到选项的目录” 下面是错误日志。 Ld /Users/user/Library/Develop
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 11 个月前关闭。 Improve t
假设我正在从 C++ 移植代码并需要在 C# 中模拟相同的位移技术: 每当我执行位移时,我是否必须考虑架构的 Endain-ness? 最佳答案 没有。位移是一种纯粹的代数运算。它不比乘以二更依赖于平
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
关于架构 XXX 的重复符号有很多问题,但我没有得到我的问题的答案。在我的场景中,我使用 Cocoapod,并导入 FMDB,但是当我集成另一个第三方 SDK 时,当我构建项目时,出现如下错误: 是否
我无法编译我的 Xcode 项目,它有重复的 ParseFacebookUtilsV4 问题 这是我的苹果 Mach-O 链接器错误: duplicate symbol _llvm.cmdline i
我对使用 MFC 的内置文档 View 体系结构的必要性有疑问。我得到了一个基于对话框的旧项目,我必须在其中用框架替换主对话框并添加功能区。它有一种文档 View 架构,创建时没有内置类,我更愿意在新
我正在构建一个协作创作工具,该工具允许用户共同编辑信息空间,该信息空间是节点和链接的可视化。一个客户端应用程序中所做的更改需要反映到所有其他客户端中。由于它是可视化的,因此可能需要经常更新潜在的大数据
如果我在 Windows(x86 和 x64)下的 .NET 上运行涉及 System.Double 的复杂计算,然后在 Mono(Linux、Unix 等)上运行,绝对有保证 以在所有情况下得到完全
当我使用 Xcode 4.6 编译我的 iPhone 应用程序时,我看到一个奇怪的错误代码: "duplicate symbols for architecture i386". 我知道这个关于文件名
我最近询问了 System.Double,并被告知计算可能因平台/架构而异。不幸的是,我找不到任何信息来告诉我这是否适用于 System.Decimal。 对于任何特定的 decimal 计算,无论平
我有一些实体,例如:Customers、Orders、Invoices。 对于它们中的每一个,我都将它们的CRUD 操作 和一些其他界面分组为:ISvcCustomerMgmt、ISvcOrderMg
这个问题有点像一个池。我们正在尝试在使用 LINQ to SQL 之类的 ORM 时确定最佳架构。我们正在定义的架构是用于其他应用程序将通过直接引用 DLL 或通过 Web 服务访问的框架。我们有 .
请就如何为 Java web 应用程序做“插件”架构提出建议。 目前我们在 Tomcat servlet 容器中使用非常简单和标准的 Spring+Hibernate+Struts 2。 (使用 ma
我是一名优秀的程序员,十分优秀!