我动态链接到fortran静态对象,并且需要能够(在运行时)获取fortran函数的名称(这是一个C字符串)并为编译器命名.是否有任何预先建立的功能可以达到此目的?在静态链接的情况下,我使用autoconf的FC_FUNC.
为清楚起见,我想要一个能够获取字符串的函数,将其解释为fortran子例程名称并对给定的编译器进行适当的修改.在psuedo-C中,:
std::string subroutine = "FORTRANSUBROUTINE";
std::string symbol = FortranMangle(subroutine);
std::cout << symbol << endl; // Would output something like "fortransubroutine_"
我不知道所有使用过的名称修改方案来编写这个神秘的“FortranMangle”函数,我自己.
解决方法:
这是一个快速而肮脏的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;
}