F77 中的不透明指针
我有一个项目,一半是 C 语言,一半是 Fortran 77 语言。 [不,不是 Fortran 90 或 03,而是 Fortran 77。] 如果我可以将 C 端生成的指针传递回 Fortran,代码会干净得多,这将然后根据需要将它们传回以在其他 C 函数中进行处理。事实上,C 代码充满了不应该是全局的全局变量,否则就会变成非结构化的混乱。那么有没有相当可靠的方法可以在 C 和 Fortran 之间传递不透明指针呢?
I have a project that is half in C and half in Fortran 77. [No, not Fortran 90 or 03, Fortran 77.] The code would be much cleaner if I could pass pointers generated on the C side back to Fortran, which would then pass them back as necessary for handling in other C functions. As it is, the C code is filled with global variables that shouldn't be global, and is otherwise on the verge of becoming an unstructured mess. So are there any reasonably reliable ways to pass an opaque pointer between C and Fortran?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您使用的是 32 位平台,请考虑将指针强制转换为整数并将这些整数传递给 Fortran 代码。当 Fortran 将它们传回时,将整数重新转换回指针,交叉手指并使用。
据我所知(25 多年前),Fortran 77 倾向于通过指针将所有内容传递给 C,并且字符串会传递长度,数组会传递其维度。
如果您使用的是 64 位平台,则必须确定 Fortran 77 编译器是否提供任何 8 字节整数(INTEGER*8?) - 我怀疑它不会(很大程度上通过查看GNU 文档;如果您使用 Fortran 2003,情况会更好,它似乎)。如果确实如此,同样的技巧也能发挥作用。如果没有,你就陷入了更加危险的境地。
您可以尝试 - 反对建议 - 使用双精度和指针的联合。在 C 中,您可以从 C 代码指针设置联合中的指针,然后将联合中的双精度值复制到 Fortran REAL*8 中,并且只要没有人触及该指针,除了复制它或传递它回来吧,如果众神对你的努力微笑,也许你会没事的。但最有可能的是,整个事情会爆炸 - 这种联合具有令人难以置信的能力,可以检测到如果某些功能不起作用,客户何时会最恼火,然后会在正确的时刻继续爆炸 - 在演示过程中,或节目上线后十五分钟。
考虑的替代方案(仍然咬牙切齿)是一个 64 位指针和两个 32 位整数的数组的联合,然后要求 Fortran 代码在需要返回 (64位)指针。显然,一个整数的数组适用于 32 位代码;也许只需要调用代码在所有情况下传递两个整数的数组,将 32 位指针情况下未使用的整数值归零?这为您提供了向前可迁移性。
If you are on a 32-bit platform, consider casting the pointers to integers and passing those integers to the Fortran code. When the Fortran passes them back, reconvert the integer back into a pointer, cross-fingers, and use.
From what I remember (from 25+ years ago), Fortran 77 tends to pass everything to C by pointer anyway - and character strings get passed with a length, and arrays get passed with their dimensions.
If you're on a 64-bit platform, you'll have to work out whether the Fortran 77 compiler provides any 8-byte integers (INTEGER*8?) - my suspicion is that it won't (largely confirmed by looking at the GNU documentation; if you were using Fortran 2003, you'd be in better shape, it seems). If it does, the same trick works. If it does not, you are into much dodgier territory.
You could try - against recommendations - using a union of a double and a pointer. In the C, you'd set the pointer in the union from your C code pointer, then copy the double out of the union into a Fortran REAL*8, and as long as no-one touches that except to copy it or pass it back, maybe you will be OK if the gods smile favourably upon your endeavours. Most likely though, the whole thing will explode - this sort of union has an incredible ability to detect when the customer will be most annoyed if something doesn't work and will then proceed to explode at exactly the right moment - part way through the demo, or fifteen minutes after the program goes live.
An alternative to consider (still with gritted teeth) is a union of a 64-bit pointer and an array of two 32-bit integers, and then requiring the Fortran code to pass an array of two integers when you need to return a (64-bit) pointer. Clearly, an array of one integer(s) would work to 32-bit code; maybe just require the calling code to pass an array of two integers in all cases, zeroing the unused integer value in the 32-bit pointer case? That gives you forward migratability.
您可以使用(非标准)Cray 指针扩展来执行此操作:
http:// /gcc.gnu.org/onlinedocs/gfortran/Cray-pointers.html
You can do this with the (non-standard) Cray pointer extension:
http://gcc.gnu.org/onlinedocs/gfortran/Cray-pointers.html