5

我想从 Fortran 调用一个 C api 函数。C 函数接受一个字节数组:

void image(const void *bitmap, int w, int h);

其中三个连续字节*bitmap表示 RGB 颜色三元组,并被解释为unsigned char在 C 中。我想在 Fortran 中初始化位图并注意在 C 中绘图。Fortran 中的当前定义使用

integer*1 rgbImage(6,2)

例如初始化 2x2 的图像,但编译器不接受赋值

rgbImage(1,1) = 255

得到红色。我已经看到将BYTE, UNSIGNED*1,LOGICAL*1用于无符号单字节的提示,但是 gfortran(MacPort 的 gcc 4.4 或 Mac OS X 下的 4.6)对它们中的任何一个都不满意。我可能会通过作弊和分配价值-1而不是 来逃脱255,但这使用起来非常不舒服。编译器标志-fno-range-check有助于编译代码,但在其他 Fortran 编译器中可能不可用,我认为这是一个丑陋的解决方案(我仍然想捕捉其他警告)。值'FF'Xor'11111111'B也被识别为 32 位整数。

非常希望代码可以跨不同的 Fortran 编译器移植。

4

2 回答 2

13

我的建议是使用CHARACTER变量,并用于ACHAR设置值(并ICHAR根据需要转换回整数)。这应该可以让您得到您想要的并且完全便携。例如,

character, dimension(6,2) :: rgbImage

rgbImage(1,1) = achar(255)

更新添加:如果您要使用 Fortran 2003 iso_c_binding 东西来连接 C 例程(强烈推荐!)那么您不妨将 rgbImage 数组字符设为 kindc_char,例如

character(kind=c_char), dimension(6,2) :: rgbImage
integer(kind=c_int) :: w, h

...
rgbImage(1,1) = achar(255)
...

call image(rgbImage, w, h)

您在哪里定义了例程的接口

 interface
    subroutine image(img, w, h) bind(C)
       use, intrinsic :: iso_c_binding
       implicit none
       integer(kind=c_int), intent(in), value :: w, h
       character(kind=c_char) :: img(:,:)
    end subroutine image
 end interface
于 2012-05-25T14:18:30.017 回答
0

可能适用于某些情况的另一种策略是将 1 字节 c int 数组传递给 Integer(1) 数组,例如 iVal(:),然后创建另一个 Int 数组,例如 Integer(2) iVal2(:),然后:

Where(iVal(:) < 0)
    iVal2(:) = -iVal(:)+127
ElseWhere
    iVal2(:) = iVal(:)
End Where

...与转换为/来回字符(有时)相比,这可能更有效/更清洁,并且需要更少的编码(有时)。

If you do a lot of this type of thing (interfacing various types of usigned's etc to Fortran), a few utility routines relying on Fortran's bit intrinsics may be a worthwhile investment (e.g. BTest(), iBSet() etc).

于 2014-02-12T22:12:53.473 回答