Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“外部的影响是什么?”;";在C++;? < > >代码>外部> C >代码> C++代码是什么?_C++_C_Linkage_Name Mangling_Extern C - Fatal编程技术网 >代码>外部> C >代码> C++代码是什么?,c++,c,linkage,name-mangling,extern-c,C++,C,Linkage,Name Mangling,Extern C" /> >代码>外部> C >代码> C++代码是什么?,c++,c,linkage,name-mangling,extern-c,C++,C,Linkage,Name Mangling,Extern C" />

“外部的影响是什么?”;";在C++;? < > >代码>外部> C >代码> C++代码是什么?

“外部的影响是什么?”;";在C++;? < > >代码>外部> C >代码> C++代码是什么?,c++,c,linkage,name-mangling,extern-c,C++,C,Linkage,Name Mangling,Extern C,例如: extern "C" { void foo(); } P>在链接时,C++编译器会以C样式查找这些函数的名称,因为在C和C++中链接的函数的名称在链接阶段是不同的。 < P>它通知C++编译器在链接时查找C函数中的函数名称,因为在C和C++中编译的函数的名称在链接阶段是不同的。 < P>它改变了函数的链接,使函数从C中被调用。在实践中,这意味着函数名不是。 < P>它改变了函数的链接,从而使函数从C. In调用。“实践”意味着函数名不是. 外“c”,使C++中的函数名具有C链接

例如:

extern "C" {
   void foo();
}

<> P>在链接时,C++编译器会以C样式查找这些函数的名称,因为在C和C++中链接的函数的名称在链接阶段是不同的。

< P>它通知C++编译器在链接时查找C函数中的函数名称,因为在C和C++中编译的函数的名称在链接阶段是不同的。

< P>它改变了函数的链接,使函数从C中被调用。在实践中,这意味着函数名不是。

< P>它改变了函数的链接,从而使函数从C. In调用。“实践”意味着函数名不是.

<代码>外“c”<代码>,使C++中的函数名具有C链接(编译器不修改名称),以便客户端C代码可以使用包含C函数的头文件链接到(使用)函数,其中包含的只是函数的声明。您的函数定义以二进制格式(由C++编译器编译),客户端C链接器将使用C名称链接到该文件。

<>由于C++具有函数名的超载,C没有,C++编译器不能只使用函数名作为唯一ID来链接,所以它通过添加参数的信息来修改名称。C编译器不需要修改名称,因为当您在C++中声明一个函数具有代码>外部“C”< /C>链接时,C.不能重载函数名,C++编译器不为链接使用的名称添加参数/参数类型信息。 正如您所知,您可以显式地指定
extern“C”
链接到每个单独的声明/定义,或者使用块将一系列声明/定义分组以具有特定链接:

extern "C" void foo(int);
extern "C"
{
   void g(char);
   int i;
}
如果您关心这些技术细节,请参见C++03标准的第7.5节,这里是一个简短的摘要(重点是
extern“C”
):

  • extern“C”
    是一种链接规范
  • 每个编译器都需要提供“C”链接
  • 链接规范只能出现在名称空间范围内
  • 所有函数类型、函数名和变量名都有语言链接,只有具有外部链接的函数名和变量名才有语言链接
  • 具有不同语言链接的两种函数类型是不同的类型,即使在其他方面相同
  • 连杆规格嵌套,内部规格决定最终连杆
  • 类成员的外部“C”被忽略
  • 最多一个具有特定名称的函数可以具有“C”链接(无论名称空间如何)
  • extern“C”
    强制函数具有外部链接(不能使其静态)
    static
    内部
    extern“C”
    有效;这样声明的实体具有内部链接,因此没有语言链接
  • <> Linkage从C++到其他语言定义的对象,以及C++语言中定义的对象,都是由实现定义和语言依赖的。只有当两种语言实现的对象布局策略足够相似时,才能实现这种链接

<代码>外部“C”/CODE使C++中的函数名具有C链接(编译器不修改名称),以便客户端C代码可以使用包含C函数的头文件链接到(使用)函数,其中只包含函数的声明。您的函数定义以二进制格式(由C++编译器编译),客户端C链接器将使用C名称链接到该文件。

<>由于C++具有函数名的超载,C没有,C++编译器不能只使用函数名作为唯一ID来链接,所以它通过添加参数的信息来修改名称。C编译器不需要修改名称,因为当您在C++中声明一个函数具有代码>外部“C”< /C>链接时,C.不能重载函数名,C++编译器不为链接使用的名称添加参数/参数类型信息。 正如您所知,您可以显式地指定
extern“C”
链接到每个单独的声明/定义,或者使用块将一系列声明/定义分组以具有特定链接:

extern "C" void foo(int);
extern "C"
{
   void g(char);
   int i;
}
如果您关心这些技术细节,请参见C++03标准的第7.5节,这里是一个简短的摘要(重点是
extern“C”
):

  • extern“C”
    是一种链接规范
  • 每个编译器都需要提供“C”链接
  • 链接规范只能出现在名称空间范围内
  • 所有函数类型、函数名和变量名都有语言链接,只有具有外部链接的函数名和变量名才有语言链接
  • 具有不同语言链接的两种函数类型是不同的类型,即使在其他方面相同
  • 连杆规格嵌套,内部规格决定最终连杆
  • 类成员的外部“C”被忽略
  • 最多一个具有特定名称的函数可以具有“C”链接(无论名称空间如何)
  • extern“C”
    强制函数具有外部链接(不能使其静态)
    static
    内部
    extern“C”
    有效;这样声明的实体具有内部链接,因此没有语言链接
  • <> Linkage从C++到其他语言定义的对象,以及C++语言中定义的对象,都是由实现定义和语言依赖的。只有当两种语言实现的对象布局策略足够相似时,才能实现这种链接

在每个C++程序中,所有非静态函数都以二进制文件的形式表示为符号。这些符号是特殊的t

extern "C" {
#include "legacy_C_header.h"
}
extern "C" {
struct method {
    int virtual;
};
}
#include <string.h>
#include <windows.h>

using namespace std;

#define DLL extern "C" __declspec(dllexport)
//I defined DLL for dllexport function
DLL main ()
{
    MessageBox(NULL,"Hi from DLL","DLL",MB_OK);
}
#include <string.h>
#include <windows.h>

using namespace std;

typedef LPVOID (WINAPI*Function)();//make a placeholder for function from dll
Function mainDLLFunc;//make a variable for function placeholder

int main()
{
    char winDir[MAX_PATH];//will hold path of above dll
    GetCurrentDirectory(sizeof(winDir),winDir);//dll is in same dir as exe
    strcat(winDir,"\\exmple.dll");//concentrate dll name with path
    HINSTANCE DLL = LoadLibrary(winDir);//load example dll
    if(DLL==NULL)
    {
        FreeLibrary((HMODULE)DLL);//if load fails exit
        return 0;
    }
    mainDLLFunc=(Function)GetProcAddress((HMODULE)DLL, "main");
    //defined variable is used to assign a function from dll
    //GetProcAddress is used to locate function with pre defined extern name "DLL"
    //and matcing function name
    if(mainDLLFunc==NULL)
    {
        FreeLibrary((HMODULE)DLL);//if it fails exit
        return 0;
    }
    mainDLLFunc();//run exported function 
    FreeLibrary((HMODULE)DLL);
}
void f() {}
void g();

extern "C" {
    void ef() {}
    void eg();
}

/* Prevent g and eg from being optimized away. */
void h() { g(); eg(); }
g++ -c -std=c++11 -Wall -Wextra -pedantic -o main.o main.cpp
readelf -s main.o
     8: 0000000000000000     7 FUNC    GLOBAL DEFAULT    1 _Z1fv
     9: 0000000000000007     7 FUNC    GLOBAL DEFAULT    1 ef
    10: 000000000000000e    17 FUNC    GLOBAL DEFAULT    1 _Z1hv
    11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _GLOBAL_OFFSET_TABLE_
    12: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z1gv
    13: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND eg
$ c++filt _Z1fv
f()
$ c++filt _Z1hv
h()
$ c++filt _Z1gv
g()
extern "C" {
    // Overloading.
    // error: declaration of C function ‘void f(int)’ conflicts with
    void f();
    void f(int i);

    // Templates.
    // error: template with C linkage
    template <class C> void f(C i) { }
}
#include <cassert>

#include "c.h"

int main() {
    assert(f() == 1);
}
#ifndef C_H
#define C_H

/* This ifdef allows the header to be used from both C and C++ 
 * because C does not know what this extern "C" thing is. */
#ifdef __cplusplus
extern "C" {
#endif
int f();
#ifdef __cplusplus
}
#endif

#endif
#include "c.h"

int f(void) { return 1; }
g++ -c -o main.o -std=c++98 main.cpp
gcc -c -o c.o -std=c89 c.c
g++ -o main.out main.o c.o
./main.out
main.cpp:6: undefined reference to `f()'
#include <assert.h>

#include "cpp.h"

int main(void) {
    assert(f_int(1) == 2);
    assert(f_float(1.0) == 3);
    return 0;
}
#ifndef CPP_H
#define CPP_H

#ifdef __cplusplus
// C cannot see these overloaded prototypes, or else it would get confused.
int f(int i);
int f(float i);
extern "C" {
#endif
int f_int(int i);
int f_float(float i);
#ifdef __cplusplus
}
#endif

#endif
#include "cpp.h"

int f(int i) {
    return i + 1;
}

int f(float i) {
    return i + 2;
}

int f_int(int i) {
    return f(i);
}

int f_float(float i) {
    return f(i);
}
gcc -c -o main.o -std=c89 -Wextra main.c
g++ -c -o cpp.o -std=c++98 cpp.cpp
g++ -o main.out main.o cpp.o
./main.out
main.c:6: undefined reference to `f_int'
main.c:7: undefined reference to `f_float'
extern "language" function-prototype
extern "language"
{
     function-prototype
};
#include<iostream>
using namespace std;

extern "C"
{
     #include<stdio.h>    // Include C Header
     int n;               // Declare a Variable
     void func(int,int);  // Declare a function (function prototype)
}

int main()
{
    func(int a, int b);   // Calling function . . .
    return 0;
}

// Function definition . . .
void func(int m, int n)
{
    //
    //
}
#include <stdio.h>

// Two functions are defined with the same name
// but have different parameters

void printMe(int a) {
  printf("int: %i\n", a);
}

void printMe(char a) {
  printf("char: %c\n", a);
}

int main() {
  printMe("a");
  printMe(1);
  return 0;
}
int  f (void) { return 1; }
int  f (int)  { return 0; }
void g (void) { int i = f(), j = f(0); }
int  __f_v (void) { return 1; }
int  __f_i (int)  { return 0; }
void __g_v (void) { int i = __f_v(), j = __f_i(0); }