与编译器无关的 Fortran 名称修改函数

发布于 2024-11-30 22:45:06 字数 482 浏览 3 评论 0原文

我动态链接到一个 Fortran 静态对象,并且需要能够(在运行时)获取 Fortran 函数的名称(这是一个 C++ 字符串),并为编译器适当地命名它。是否有任何预先构建的功能可以达到此目的?在静态链接的情况下,我使用 autoconf 的 FC_FUNC。

为了清楚起见,我想要一个能够接受字符串、将其解释为 Fortran 子例程名称并针对给定编译器适当地处理它的函数。在伪 C++ 中:

std::string subroutine = "FORTRANSUBROUTINE";
std::string symbol     = FortranMangle(subroutine);

std::cout << symbol << endl; // Would output something like "fortransubroutine_"

我自己不知道编写这个神秘的“FortranMangle”函数所使用的所有名称修改方案。

I am dynamically linking to a fortran static object and need to be able (at run time) to take the name of the fortran function (which is a C++ string) and name mangle it appropriately for the compiler. Is there any pre-built function that would serve this purpose? In the statically linked case I am using autoconf's FC_FUNC.

For clarity, I want a function that would be able to take a string, interpret it as a fortran subroutine name and mangle it appropriately for the given compiler. In psuedo-C++,:

std::string subroutine = "FORTRANSUBROUTINE";
std::string symbol     = FortranMangle(subroutine);

std::cout << symbol << endl; // Would output something like "fortransubroutine_"

I do not know all of the used name mangling schemes to write this mysterious "FortranMangle" function, myself.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

牵你手 2024-12-07 22:45:06

我假设您想在运行时使用 dlopen 从 C 访问 fortran 例程。由于符号根据 Fortran 编译器而变化,因此您不知道要传递给 dlsym 的内容才能获取符号。

一种可能的解决方案是使用 BIND(C)。这消除了名称修改并使用 C 样式符号名称,即一对一映射。

另一种方法是您知道如何进行重整,并相应地实现 FortranMangle 例程。没有为此预先准备任何东西,因为重整是特定于编译器的,并且规范中没有任何相关内容。

I assume you want to access fortran routines in runtime from C with dlopen. Since the symbol changes according to the fortran compiler, you don't know what to pass to dlsym in order to get the symbol.

one possible solution is to specify the fortran routine you want to call with BIND(C). This removes name mangling and uses C-style symbol name, that is, one-to-one mapping.

The alternative is that you know how the mangling is done, and implement the FortranMangle routine accordingly. There's nothing premade for that, because mangling is compiler specific and there's nothing in the spec about this.

魂归处 2024-12-07 22:45:06

这是一个快速但肮脏的 C 解决方案,它滥用现有的宏来提取损坏规则并打印损坏结果。其中大部分都会被优化器忽略,因此只存在相关的情况。您应该能够使其适应您的代码。

#include <stdio.h>
#include <string.h>

/* The autoconf macros, predefined here for uppercase, underscore,
 * extra underscore */
#define FC_FUNC(name, NAME) NAME ## _
#define FC_FUNC_(name, NAME) NAME ## __

#define STR(arg) STR1(arg)
#define STR1(arg) #arg

int main(int argc, char **argv)
{
    const char normal[] = STR(FC_FUNC(l, U));
    const char w_uscore[] = STR(FC_FUNC_(l, U));
    char ucase, uscore, extra_uscore;
    char buf[256];
    int i;

    ucase = normal[0] == 'l' ? 0 : 1;
    if (sizeof(normal) > sizeof("l"))
        uscore = 1;
    else
        uscore = 0;

    if (sizeof(w_uscore) > sizeof(normal))
        extra_uscore = 1;
    else
        extra_uscore = 0;

    printf("upper: %d uscore: %d extra :%d\n", ucase, uscore, extra_uscore);

    if (argc < 2)
        return -1;

    /* Copy string, converting case */
    for (i=0; i < strlen(argv[1]); i++)
    {
        buf[i] = ucase ? toupper(argv[1][i]) : tolower(argv[1][i]);
    }

    if (uscore)
        buf[i++] = '_';

    if (extra_uscore && strchr(argv[1], '_'))
    {
        buf[i++] = '_';
    }

    buf[i] = '\0';

    printf("old: %s - new %s\n", argv[1], buf);

    return 0;
}

Here's a quick and dirty C solution that abuses the existing macros to extract the mangling rules and print the mangled result. Most of this gets elided by the optimizer, so only the relevant cases exist. You should be able to adapt this to your code.

#include <stdio.h>
#include <string.h>

/* The autoconf macros, predefined here for uppercase, underscore,
 * extra underscore */
#define FC_FUNC(name, NAME) NAME ## _
#define FC_FUNC_(name, NAME) NAME ## __

#define STR(arg) STR1(arg)
#define STR1(arg) #arg

int main(int argc, char **argv)
{
    const char normal[] = STR(FC_FUNC(l, U));
    const char w_uscore[] = STR(FC_FUNC_(l, U));
    char ucase, uscore, extra_uscore;
    char buf[256];
    int i;

    ucase = normal[0] == 'l' ? 0 : 1;
    if (sizeof(normal) > sizeof("l"))
        uscore = 1;
    else
        uscore = 0;

    if (sizeof(w_uscore) > sizeof(normal))
        extra_uscore = 1;
    else
        extra_uscore = 0;

    printf("upper: %d uscore: %d extra :%d\n", ucase, uscore, extra_uscore);

    if (argc < 2)
        return -1;

    /* Copy string, converting case */
    for (i=0; i < strlen(argv[1]); i++)
    {
        buf[i] = ucase ? toupper(argv[1][i]) : tolower(argv[1][i]);
    }

    if (uscore)
        buf[i++] = '_';

    if (extra_uscore && strchr(argv[1], '_'))
    {
        buf[i++] = '_';
    }

    buf[i] = '\0';

    printf("old: %s - new %s\n", argv[1], buf);

    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文