C++ 使用g+编译gcc.o文件+。cpp文件

C++ 使用g+编译gcc.o文件+。cpp文件,c++,c,gcc,g++,object-files,C++,C,Gcc,G++,Object Files,我有两个文件,print_permu.c和gen_permu.cpp。我希望将print_permu.c文件编译成一个目标文件,然后使用该目标文件编译gen_permu.cpp,其中包含对print_permu.c中函数的调用 print\u permu.c #include<stdlib.h> #include<stdio.h> typedef char byte; char *printable=NULL; size_t pos,size,*char_cnt;

我有两个文件,
print_permu.c
gen_permu.cpp
。我希望将
print_permu.c
文件编译成一个目标文件,然后使用该目标文件编译
gen_permu.cpp
,其中包含对
print_permu.c
中函数的调用

print\u permu.c

#include<stdlib.h>
#include<stdio.h>

typedef char byte;

char *printable=NULL;
size_t pos,size,*char_cnt;

void __print_permu_recurse()
{
        if( pos==size )
        {
                printf("%s\n",printable);
                return;
        }
        byte iter = 25;
        while( iter>=0 )
        {
                if( char_cnt[iter] )
                {
                        printable[pos] = 'a'+iter;
                        --char_cnt[iter];
                        ++pos;
                        __print_permu_recurse();
                        --pos;
                        ++char_cnt[iter];
                }
                --iter;
        }
}

void print_permu(size_t *char_count)
{
        char_cnt = char_count;
        for(pos = 0,size = 0 ; pos<26 ; ++pos)
                size += char_count[pos];

        printable = (char*)malloc(sizeof(char)*(size+1));
        printable[size] = '\0';
        pos = 0;

        __print_permu_recurse();

        free(printable);
}
我尝试了以下命令以上述方式编译代码

$ gcc -c print_permu.c 
$ g++ print_permu.o gen_permu.cpp 
/tmp/ccQxAEea.o:(.bss+0x0): multiple definition of `printable'
print_permu.o:(.bss+0x0): first defined here
/tmp/ccQxAEea.o: In function `__print_permu_recurse':
gen_permu.cpp:(.text+0x0): multiple definition of `__print_permu_recurse'
print_permu.o:print_permu.c:(.text+0x0): first defined here
/tmp/ccQxAEea.o: In function `print_permu':
gen_permu.cpp:(.text+0xe0): multiple definition of `print_permu'
print_permu.o:print_permu.c:(.text+0xe9): first defined here
collect2: error: ld returned 1 exit status

$ g++ -c print_permu.c 
$ g++ print_permu.o gen_permu.cpp 
/tmp/ccPJA0kU.o:(.bss+0x0): multiple definition of `printable'
print_permu.o:(.bss+0x0): first defined here
/tmp/ccPJA0kU.o:(.bss+0x8): multiple definition of `pos'
print_permu.o:(.bss+0x8): first defined here
/tmp/ccPJA0kU.o:(.bss+0x10): multiple definition of `size'
print_permu.o:(.bss+0x10): first defined here
/tmp/ccPJA0kU.o:(.bss+0x18): multiple definition of `char_cnt'
print_permu.o:(.bss+0x18): first defined here
collect2: error: ld returned 1 exit status
首先,我使用
gcc
编译代码,希望在使用
g++
编译时目标文件能够兼容。那没用。因此,我试图单独使用
g++
编译这两个文件,但都没有用

我如何编译这段代码?”我是否缺少任何选择

使用gcc版本4.8.4(Ubuntu 4.8.4-2ubuntu1~14.04)、Ubuntu 14.04、x86_64


另外,


我最初想声明
print\u permu\u recurse
函数中的
print\u permu
,这在gcc中是允许的(尽管不是C标准)。我也遵循了类似的过程。因为这没有解决,即使用C++来改变代码也要兼容。

您的问题是这个结构在<代码> GEYPARMUM.CPP:

extern "C"
{
        #include"print_permu.c"
}
您有一个源文件
print\u permu.c
,还有一个源文件
gen\u permu.cpp
,其中包括
print\u permu.c

当您将
print\u permu.c
编译为目标代码时,它包含了从源文件
print\u permu.c
的所有内容

当您将
gen_permu.cpp
编译为目标代码时,它包含从源文件
gen_permu.cpp
到源文件
print_permu.c
的所有内容

当您试图将两者链接在一起时,会出现“多定义”错误,因为
print\u permu.c
中的所有内容都在
gen\u permu.cpp
中定义,链接器在决定使用哪个定义时会犹豫


您可能想要做的是包含来自
print\u permu.c
的声明。这不是通过包含整个源文件来实现的,而是通过写入头文件来实现的

// This is a "header guard". It avoids problems if the
// header is included more than once in a translation unit.
// The token used (here: PRINT_PERMU_H) is up to you, but
// should be sufficiently unique. All uppercase is a common
// convention.
#ifndef PRINT_PERMU_H
#define PRINT_PERMU_H

// This makes a C++ compiler aware that function declarations
// refer to *C* code, not C++ code. (The two languages generate
// different linker symbols.) A C compiler will just ignore this
// (as it should, since it does not need any special handling).
#ifdef __cplusplus
extern "C" {
#endif

// This just *declares* the *existence* of the function.
// The compiler can use this information (in gen_permu.cpp)
// to create a call-to-placeholder. The linker will then
// turn that into a call-to-function when you link the two
// object files together.
void print_permu(size_t *char_count);

// End of the C++ compatibility construct.    
#ifdef __cplusplus
}
#endif

// End of the header guard.
#endif
然后,代替顶部的构造,只需编写

#include "print_permu.h"
<>在C++文件(或C文件中,这不需要考虑到<代码> >
您的源代码还存在其他各种问题,这些问题不会立即导致失败,但如果它们成为编码习惯,则会带来问题:

无注释,并且假设ASCII

我敢肯定,假设ASCII-7字符集,您的代码会对字符进行一些可疑的操作,如果1)文本包含国际字符(如öß),或者2)所讨论的系统具有非连续字符编码(例如)

但我厌倦了试图弄清楚你的代码实际上打算做什么,因为里面没有任何注释。(假设我发布了没有注释的标题示例…)所以我不能给你提示如何改进,只是你应该这样做


我还看到一个不带大括号(
{}
)的
for
循环

您的问题在于
gen_permu.cpp
中的构造:

extern "C"
{
        #include"print_permu.c"
}
您有一个源文件
print\u permu.c
,还有一个源文件
gen\u permu.cpp
,其中包括
print\u permu.c

当您将
print\u permu.c
编译为目标代码时,它包含了从源文件
print\u permu.c
的所有内容

当您将
gen_permu.cpp
编译为目标代码时,它包含从源文件
gen_permu.cpp
到源文件
print_permu.c
的所有内容

当您试图将两者链接在一起时,会出现“多定义”错误,因为
print\u permu.c
中的所有内容都在
gen\u permu.cpp
中定义,链接器在决定使用哪个定义时会犹豫


您可能想要做的是包含来自
print\u permu.c
的声明。这不是通过包含整个源文件来实现的,而是通过写入头文件来实现的

// This is a "header guard". It avoids problems if the
// header is included more than once in a translation unit.
// The token used (here: PRINT_PERMU_H) is up to you, but
// should be sufficiently unique. All uppercase is a common
// convention.
#ifndef PRINT_PERMU_H
#define PRINT_PERMU_H

// This makes a C++ compiler aware that function declarations
// refer to *C* code, not C++ code. (The two languages generate
// different linker symbols.) A C compiler will just ignore this
// (as it should, since it does not need any special handling).
#ifdef __cplusplus
extern "C" {
#endif

// This just *declares* the *existence* of the function.
// The compiler can use this information (in gen_permu.cpp)
// to create a call-to-placeholder. The linker will then
// turn that into a call-to-function when you link the two
// object files together.
void print_permu(size_t *char_count);

// End of the C++ compatibility construct.    
#ifdef __cplusplus
}
#endif

// End of the header guard.
#endif
然后,代替顶部的构造,只需编写

#include "print_permu.h"
<>在C++文件(或C文件中,这不需要考虑到<代码> >
您的源代码还存在其他各种问题,这些问题不会立即导致失败,但如果它们成为编码习惯,则会带来问题:

无注释,并且假设ASCII

我敢肯定,假设ASCII-7字符集,您的代码会对字符进行一些可疑的操作,如果1)文本包含国际字符(如öß),或者2)所讨论的系统具有非连续字符编码(例如)

但我厌倦了试图弄清楚你的代码实际上打算做什么,因为里面没有任何注释。(假设我发布了没有注释的标题示例…)所以我不能给你提示如何改进,只是你应该这样做


我还看到一个不带大括号(
{}
)的
for
循环

首先,不要使用带有双前导下划线的名称,它们在所有作用域中都是保留的。其次,不要将源文件包含到另一个源文件中。相反,创建一个包含要调用的函数的函数原型的头文件,并将其包括在内。从不
#include
a
.c
文件,因为没有理由这样做。它只适用于创建链接器错误。您需要为.c文件中的函数原型创建一个.h文件。.h应该检查正在定义的cplusplus,如果已定义,则在.h文件中使用extern c{…}语法#将该.h文件同时包含在.c和.cpp文件中首先,不要使用带有双前导下划线t的名称