10
votes

Conversion du fichier d'objet C ++ de Linux .o vers Windows .OBJ

Je suis désolé si cela semble fou. Y a-t-il de toute façon je peux convertir .o fichier que je reçois du compilateur g ++ à * obj compatible avec Visual Studio.

Ceci est la raison pour laquelle je compte faire cette conversion.


5 commentaires

Je doute que cela soit possible, mais je serais intéressé à entendre une réponse.


Visual Studio est livré avec un compilateur. Utilisez simplement cela pour convertir votre fichier source en un fichier d'objet compatible avec Visual Studio.


@Rafid, c'est possible. Voir ma réponse. Je l'ai fait pour mon code GEMM et mon code de jeu Mandelbrot. Dans les deux cas à l'aide de l'objet compilé par GCC dans Visual Studio, il est beaucoup plus rapide, car GCC optimise mieux.


@DavidHeffernan, GCC optimise mieux que le compilateur Visual Studio, alors qu'est-ce qui ne va pas avec la GCC dans les régions dont vous avez besoin de performance dans Visual Studio?


@Zboson, intéressant! Vous méritez +1!


3 Réponses :


1
votes

Non, il n'y a aucun moyen, d'autant plus que le fichier .o n'a pas été compilé avec un compilateur croisé sous Linux. Dans tous les cas, cela ressemble à une approche très étrange pour résoudre une seule erreur de liaison.


0 commentaires

3
votes

hmm, techniquement, la commande ObjCopy qui fait partie de GNU Bintules pourrait être capable de le faire. Cependant, et c'est un énorme, cependant, la conversion du format ne suffit pas. Vous auriez besoin d'une version du compilateur G ++ qui possède les conventions d'appel exactes et le nom de Nom Mangrling en tant que VC ++ pour commencer et la même idée de compiler des structures, etc.

convertir physiquement le fichier en un fichier .OBJ valide peut bien être possible, mais ce n'est probablement pas très utile pour vous.


0 commentaires

14
votes

Il y a un moyen de faire cela et ce n'est pas si difficile.

Les principales choses que vous devez savoir sont les conventitions d'appel Fonction, le format d'objet et le nom de la fonction mangling. strong>

Conventions d'appel de fonction. h2>

en mode 32 bits Windows et UNIX (c.-à-d. Linux, BSD, Mac OS X, ...) Utilisez la même fonction Calling Conventions. P>

en mode 64 bits Windows et UNIX Utilisez des conventions d'appel de fonctions différentes. Pour que votre fichier d'objet compilé avec GCC fonctionne avec MSVC en mode 64 bits, vous devez utiliser la convention d'appel de la fonction Windows. Pour ce faire avec GCC, vous pouvez utiliser MABI = ms code> par exemple: p> xxx pré>

le format de fichier d'objet h2>

Le fichier d'objet Le format pour Linux est ELF et pour Windows C'est COFF / PE. Afin d'utiliser un objet compilé avec GCC dans MSVC, il doit être converti de ELF en COFF. Pour ce faire, vous avez besoin d'un convertisseur de fichier d'objet. J'utilise objconv . Par exemple, de convertir de ELF64 à 64 bits CoFC64 (PE32 +) DO: P>

#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);
}


2 commentaires

Qu'en est-il des différences de format TTAble C ++? Autant que je puisse voir que votre solution ne fonctionnera qu'avec C ++ C ++ C ++ (pas de classes de manière significative avec polymorphisme).


@Vesnik, je ne sais pas. Je n'ai utilisé que cette "astuce" pour ne pas avoir à apprendre l'assemblée 64 bits pour que MSVC fasse ce que je voulais (quel GCC faisait déjà). Je n'ai testé que sur des exemples tels que dans cette réponse.