gpt4 book ai didi

c++ - 将 C++ 目标文件从 linux .o 转换为 Windows .obj

转载 作者:可可西里 更新时间:2023-11-01 15:47:58 26 4
gpt4 key购买 nike

如果这听起来很疯狂,我很抱歉。无论如何我可以将从 g++ 编译器获得的 .o 文件转换为与 Visual Studio 兼容的 *obj。

This是我考虑进行此转换的原因。

最佳答案

有一种方法可以做到这一点,而且并不难。

您需要了解的主要内容是函数调用约定、对象格式和函数名称重整。

函数调用约定。

在 32 位模式下,Windows 和 Unix(即 Linux、BSD、Mac OS X...)使用相同的函数调用约定。

在 64 位模式下,Windows 和 Unix 使用不同的函数调用约定。为了使使用 GCC 编译的目标文件能够在 64 位模式下与 MSVC 一起使用,您必须使用 Windows 函数调用约定。要使用 gcc 做到这一点,您可以使用 mabi=ms 例如:

g++ -c -mabi=ms -mavx -fopenmp -O3 foo.cpp

目标文件格式

Linux 的目标文件格式是 ELF,Windows 是 COFF/PE。为了在 MSVC 中使用使用 GCC 编译的对象,需要将其从 ELF 转换为 COFF。为此,您需要一个目标文件转换器。我使用 Agner Fog 的 objconv .例如,要从 ELF64 转换为 64 位 COFF64 (PE32+),请执行以下操作:

objconv -fcoff64 foo.o foo.obj

函数名称修改

由于函数重载,C++ 破坏了函数名称。 GCC 和 MSVC 的做法不同。要解决此问题,您可以使用 external "C" 继续函数名称。

有关调用约定、对象格式和函数名称修改的更多详细信息,请参阅 Agner Fog 的手册 calling conventions .

下面是我用 GCC 编译然后在 MSVC (because GCC optimized it better) 中使用的模块。我用 -mabi=ms 编译它,用 objconv 将它转换为 COFF64,然后将它链接到运行完美的 Visual Studio。

#include <immintrin.h>
extern "C" void inner(const int n, const float *a, const float *b, float *c, const int stridea, const int strideb, const int stridec) {
const int vec_size = 8;
__m256 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
tmp0 = _mm256_loadu_ps(&c[0*vec_size]);
tmp1 = _mm256_loadu_ps(&c[1*vec_size]);
tmp2 = _mm256_loadu_ps(&c[2*vec_size]);
tmp3 = _mm256_loadu_ps(&c[3*vec_size]);
tmp4 = _mm256_loadu_ps(&c[4*vec_size]);
tmp5 = _mm256_loadu_ps(&c[5*vec_size]);
tmp6 = _mm256_loadu_ps(&c[6*vec_size]);
tmp7 = _mm256_loadu_ps(&c[7*vec_size]);

for(int i=0; i<n; i++) {
__m256 areg0 = _mm256_set1_ps(a[i]);

__m256 breg0 = _mm256_loadu_ps(&b[vec_size*(8*i + 0)]);
tmp0 = _mm256_add_ps(_mm256_mul_ps(areg0,breg0), tmp0);
__m256 breg1 = _mm256_loadu_ps(&b[vec_size*(8*i + 1)]);
tmp1 = _mm256_add_ps(_mm256_mul_ps(areg0,breg1), tmp1);
__m256 breg2 = _mm256_loadu_ps(&b[vec_size*(8*i + 2)]);
tmp2 = _mm256_add_ps(_mm256_mul_ps(areg0,breg2), tmp2);
__m256 breg3 = _mm256_loadu_ps(&b[vec_size*(8*i + 3)]);
tmp3 = _mm256_add_ps(_mm256_mul_ps(areg0,breg3), tmp3);
__m256 breg4 = _mm256_loadu_ps(&b[vec_size*(8*i + 4)]);
tmp4 = _mm256_add_ps(_mm256_mul_ps(areg0,breg4), tmp4);
__m256 breg5 = _mm256_loadu_ps(&b[vec_size*(8*i + 5)]);
tmp5 = _mm256_add_ps(_mm256_mul_ps(areg0,breg5), tmp5);
__m256 breg6 = _mm256_loadu_ps(&b[vec_size*(8*i + 6)]);
tmp6 = _mm256_add_ps(_mm256_mul_ps(areg0,breg6), tmp6);
__m256 breg7 = _mm256_loadu_ps(&b[vec_size*(8*i + 7)]);
tmp7 = _mm256_add_ps(_mm256_mul_ps(areg0,breg7), tmp7);
}
_mm256_storeu_ps(&c[0*vec_size], tmp0);
_mm256_storeu_ps(&c[1*vec_size], tmp1);
_mm256_storeu_ps(&c[2*vec_size], tmp2);
_mm256_storeu_ps(&c[3*vec_size], tmp3);
_mm256_storeu_ps(&c[4*vec_size], tmp4);
_mm256_storeu_ps(&c[5*vec_size], tmp5);
_mm256_storeu_ps(&c[6*vec_size], tmp6);
_mm256_storeu_ps(&c[7*vec_size], tmp7);
}

关于c++ - 将 C++ 目标文件从 linux .o 转换为 Windows .obj,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4770918/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com