C语言 根据体系结构选择要调用的函数

bttbmeg0  于 2023-06-21  发布在  其他
关注(0)|答案(2)|浏览(136)

我主要在NASM中工作,但是我也在制作一个C/C++头文件,它使用extern s将函数从NASM导入到项目中。我担心有人在x86环境中使用x64 NASM。我知道这是不可能的(在x86中运行x64),因为我在编译时得到了无效的操作数大小错误。我计划重新制作这个项目,但在x86中,所以它可以在x86或x64中工作。
我的麻烦开始于声明extern "C"函数。
我想保留一个函数名(例如openfile),但根据定义的宏是arch_x64还是arch_x86,定义基于x64变体或x86变体。
我可以使用预处理,如下面的例子:

#ifdef arch_x64
    int value = 1;
#elif arch_x86
    int value = 0;
#endif

如果我在源项目中声明arch_x64value就是1
我想对函数openfile使用相同的方法。根据体系结构,函数 * 定义 * 应该是x64或x86。
我能做的

#ifdef arch_x64
    extern "C" void openfile64();
#elif arch_x86
    extern "C" void openfile32();
#endif

void openfile()
{
    #ifdef arch_x64
        openfile64(); // 64-bit version
    #elif arch_x86
        openfile32(); // 32-bit version
    #endif
};

这样就可以了,但是openfile64函数是可以访问的,这可能会让人感到困惑。
有没有办法将openfile的定义分配给x64(openfile64)或x86(openfile32)版本?

编辑

我刚刚意识到Jan Schultke的意思是使用.cpp文件或类似文件来隐藏openfile64。这可以工作,但我不能检测.cpp文件中的#define。我需要向.cpp文件发送一些东西,告诉它设置为什么函数(或者我想得太多了,有一个更简单的方法)。这个“东西”(同样,除非我想得太难)也会暴露在头文件中。除了函数openfile之外,我不想公开任何新内容。

eqfvzcg8

eqfvzcg81#

你正在寻找的是ifunc(间接函数)。它是GNU/GCC工具链的一个功能,允许开发人员创建给定函数的多个实现,并在运行时使用resolver函数选择其中一个。添加了一个函数属性来指定解析器函数。这就是为特定的微架构调用glibc函数(如memcpy/memmove)的正确实现的方式。llvm toolchain也支持这一点。
参考文献:

zy1mlcev

zy1mlcev2#

使用您的工具链可能是一种替代方法:
code_x86.cpp

#ifdef arch_x64
# error "wrong arch"
#endif

void openfile() // openfile32 implementation
{
    /*..*/ // 32-bit version
}

code_x64.cpp

#ifdef arch_x86
# error "wrong arch"
#endif

void openfile() // openfile64 implementation 
{
    /*..*/ // 64-bit version
}

然后只包含与您的体系结构匹配的文件。

相关问题