හරියටම දමා නැත extern "C"
C ++ කේතය කරන්නේ?
උදාහරණයක් වශයෙන්:
extern "C" {
void foo();
}
foo()
.
හරියටම දමා නැත extern "C"
C ++ කේතය කරන්නේ?
උදාහරණයක් වශයෙන්:
extern "C" {
void foo();
}
foo()
.
Answers:
බාහිර "C" මඟින් C ++ හි ක්රියාකාරී නාමයක් 'C' සම්බන්ධතාවයක් ඇති කරයි (සම්පාදකයාගේ නම හසුරුවන්නේ නැත) එවිට ග්රාහක C කේතයට 'C' අනුකූල ශීර්ෂ ගොනුවක් භාවිතා කර ඔබේ ශ්රිතයට සම්බන්ධ විය හැකිය (එනම් භාවිතා කරන්න) ඔබේ කාර්යය ප්රකාශ කිරීම. ඔබේ ක්රියාකාරී අර්ථ දැක්වීම ද්විමය ආකෘතියකින් (ඔබේ C ++ සම්පාදකයා විසින් සම්පාදනය කරන ලද) අඩංගු වන අතර එමඟින් සේවාදායකයා 'C' සම්බන්ධකය 'C' නම භාවිතා කිරීමට සම්බන්ධ වේ.
C ++ හි ක්රියාකාරී නම් අධික ලෙස පැටවීම සහ C නොමැති නිසා, C ++ සම්පාදකයාට ශ්රිත නාමය සම්බන්ධ කිරීම සඳහා අද්විතීය හැඳුනුම්පතක් ලෙස භාවිතා කළ නොහැක, එබැවින් එය තර්ක පිළිබඳ තොරතුරු එකතු කිරීමෙන් නම වෙනස් කරයි. සී හි ක්රියාකාරී නාමයන් අධික ලෙස පැටවිය නොහැකි බැවින් AC සම්පාදකයාට නම හැසිරවීමට අවශ්ය නොවේ. ශ්රිතයකට C ++ හි බාහිර "C" සම්බන්ධතාවයක් ඇති බව ඔබ ප්රකාශ කරන විට, C ++ සම්පාදකයා භාවිතා කරන නමට තර්ක / පරාමිති වර්ගයේ තොරතුරු එකතු නොකරයි. සම්බන්ධතාවය.
ඔබ දන්නා පරිදි, ඔබට එක් එක් ප්රකාශය / අර්ථ දැක්වීම සඳහා “සී” සම්බන්ධතාවය පැහැදිලිව සඳහන් කළ හැකිය, නැතහොත් නිශ්චිත සම්බන්ධතාවයක් ඇති කර ගැනීම සඳහා ප්රකාශන / අර්ථ දැක්වීම් මාලාවක් කාණ්ඩ කිරීමට බ්ලොක් එකක් භාවිතා කරන්න:
extern "C" void foo(int);
extern "C"
{
void g(char);
int i;
}
ඔබ තාක්ෂණික ක්රම ගැන සැලකිලිමත් වන්නේ නම්, ඒවා C ++ 03 ප්රමිතියේ 7.5 වගන්තියේ ලැයිස්තුගත කර ඇත, මෙහි කෙටි සාරාංශයක් ඇත (බාහිර "C" අවධාරණය කරමින්):
extern "C" { int i; }
අර්ථ නිරූපනයක් වේ. නිර්වචනය නොකිරීමට යාබදව ඔබ අදහස් කළ දේ මෙය නොවිය හැකිය void g(char);
. එය අර්ථ දැක්වීමක් නොවන බවට පත් කිරීමට ඔබට අවශ්ය වනු ඇත extern "C" { extern int i; }
. අනෙක් අතට, සඟල වරහන් තොරව එක්-ප්රකාශය කාරක රීති ප්රකාශයට පත් නොවන අර්ථ දැක්වීම සිදු කරන්නේ: extern "C" int i;
ම යextern "C" { extern int i; }
මට තව තොරතුරු පළ කිරීමට අවශ්ය නැති නිසා, තොරතුරු ටිකක් එකතු කිරීමට අවශ්ය විය.
ඔබ බොහෝ විට C ශීර්ෂ වල කේතය දකිනු ඇත:
#ifdef __cplusplus
extern "C" {
#endif
// all of your legacy C code here
#ifdef __cplusplus
}
#endif
මෙයින් ඉටු වන දෙය නම්, ඔබේ සී ++ කේතය සමඟ එම සී ශීර්ෂ ගොනුව භාවිතා කිරීමට ඔබට ඉඩ සලසයි, මන්ද සාර්ව "__cplusplus" යන්න අර්ථ දක්වනු ඇත. එහෙත්, ඔබ හැකි ද තවමත් එය සාර්ව වන ඔබේ උරුමය සී කේතය, සමග භාවිතා නොවේ අර්ථ, එය, සුවිශේෂ C ++ ඉදිකිරීමක් දැකිය නොහැක එසේ.
කෙසේ වෙතත්, මම C ++ කේතය ද දැක ඇත්තෙමි:
extern "C" {
#include "legacy_C_header.h"
}
මම හිතන විදියටම එකම දේ ඉටු වේ.
වඩා හොඳ කුමන මාර්ගයදැයි විශ්වාස නැත, නමුත් මම දෙකම දැක ඇත්තෙමි.
extern "C"
ශීර්ෂ පා saw යේ දුටු නිසා පාලනය නොකළ නම් ද සොයනු ඇත ). එය විශිෂ්ට ලෙස ක්රියා කරයි, මෙම තාක්ෂණය බොහෝ වාරයක් භාවිතා කර ඇත.
extern "C"
එය ශීර්ෂකය ඇතුළත් කිරීමට පෙර හෝ පසුව හමුවන්නේද යන්න අඩු සැලකිල්ලක් දැක්විය නොහැක . එය සම්පාදකයා වෙත ළඟා වන විට, එය කෙසේ හෝ පෙර සැකසූ පෙළක එක් දිගු ප්රවාහයක් පමණි.
g++
අවම වශයෙන් වසර 17 කට ඕනෑම වේලාවක ඕනෑම ඉලක්කයක් සඳහා, මෙම වැරදි විය. පළමු උදාහරණයේ සමස්ත කරුණ නම්, ඔබ සී හෝ සී ++ සම්පාදකයෙකු භාවිතා කළත් කමක් නැත, extern "C"
බ්ලොක් එකේ නම් සඳහා නම් මැන්ග්ලිං කිරීමක් සිදු නොවේ .
සිදුවන්නේ g++
කුමක්දැයි බැලීමට ජනනය කරන ලද ද්විමය විසංයෝජනය කරන්න
main.cpp
void f() {}
void g();
extern "C" {
void ef() {}
void eg();
}
/* Prevent g and eg from being optimized away. */
void h() { g(); eg(); }
ජනනය කරන ලද ELF ප්රතිදානය සම්පාදනය කර විසුරුවා හරින්න :
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
අර්ථ නිරූපණය
අපට එය පෙනේ:
ef
හා eg
කේතය දී මෙන් ම නම සංකේත තුළ ගබඩා කර ඇත
අනෙක් සංකේත අඹරන ලදි. අපි ඒවා පාලනය නොකරමු:
$ c++filt _Z1fv
f()
$ c++filt _Z1hv
h()
$ c++filt _Z1gv
g()
නිගමනය: පහත දැක්වෙන සංකේත වර්ග දෙකම අඹරන ලද්දේ නැත :
Ndx = UND
), වෙනත් වස්තු ගොනුවකින් සබැඳිය හෝ ක්රියාත්මක වේලාවට සැපයීමටඑබැවින් ඇමතීමේදී ඔබට extern "C"
දෙකම අවශ්ය වේ :
g++
විසින් නිපදවන ලද පාලනය නොකළ සංකේත අපේක්ෂා කිරීමට කියන්නgcc
g++
සඳහා පාලනය නොකළ සංකේත ජනනය කිරීමට කියන්නgcc
බාහිර C හි ක්රියා නොකරන දේවල්
නම මැන්ග්ලිං අවශ්ය ඕනෑම C ++ අංගයක් ඇතුළත ක්රියා නොකරන බව පැහැදිලිය extern C
:
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) { }
}
C ++ උදාහරණයෙන් ධාවනය කළ හැකි අවම සී
සම්පූර්ණත්වය සහ එහි ඇති නවකයන් සඳහා, මෙයද බලන්න: C ++ ව්යාපෘතියක C ප්රභව ගොනු භාවිතා කරන්නේ කෙසේද?
C ++ වෙතින් C ඇමතීම පහසුය: සෑම C ශ්රිතයකටම ඇත්තේ එක් කළ නොහැකි සංකේතයක් පමණි, එබැවින් අමතර වැඩක් අවශ්ය නොවේ.
main.cpp
#include <cassert>
#include "c.h"
int main() {
assert(f() == 1);
}
ch
#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
cc
#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
extern "C"
සබැඳිය නොමැතිව අසමත් වන්නේ:
main.cpp:6: undefined reference to `f()'
මක්නිසාද යත් , නිපදවා නැති , g++
අඹ ගෙඩියක් සොයා ගැනීමට අපේක්ෂා කරන බැවිනි .f
gcc
සී උදාහරණයෙන් ධාවනය කළ හැකි අවම C ++
C වෙතින් C ++ ඇමතීම ටිකක් අමාරුයි: අපට නිරාවරණය කිරීමට අවශ්ය එක් එක් ශ්රිතයේ අතින් නොවන අනුවාදයන් අප විසින් අතින් නිර්මාණය කළ යුතුය.
සී ++ ශ්රිත අධි බර සී වෙත නිරාවරණය කරන්නේ කෙසේද යන්න මෙහිදී අපි නිදර්ශනය කරමු.
main.c
#include <assert.h>
#include "cpp.h"
int main(void) {
assert(f_int(1) == 2);
assert(f_float(1.0) == 3);
return 0;
}
cpp.h.
#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
cpp.cpp
#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
extern "C"
එය නොමැතිව අසමත් වේ:
main.c:6: undefined reference to `f_int'
main.c:7: undefined reference to `f_float'
නිසා g++
ඇති තැලී පොඩි වී ගිය සංකේත ජනනය gcc
කළ හැකි වැඩක් නැහැ.
උබුන්ටු 18.04 හි පරීක්ෂා කර ඇත.
extern "C" {
ඇමතීමට උපකාරී වන බව පැහැදිලිව සඳහන් කරන්න , අනෙක් පිළිතුරු එතරම් පැහැදිලිව නොපෙන්වයි , සහ 2) ඔබ පැහැදිලි උදාහරණ පෙන්වන නිසා සෑම. ස්තූතියි!
සෑම C ++ වැඩසටහනකදීම, සියලු ස්ථිතික නොවන කාර්යයන් ද්විමය ගොනුවේ සංකේත ලෙස නිරූපණය කෙරේ. මෙම සංකේත වැඩසටහනේ ශ්රිතයක් අද්විතීය ලෙස හඳුනා ගන්නා විශේෂ පෙළ නූල් වේ.
C හි, සංකේත නාමය ශ්රිත නාමයට සමාන වේ. මෙය කළ හැකි වන්නේ සී හි ස්ථිතික නොවන ශ්රිත දෙකකට එකම නමක් තිබිය නොහැකි බැවිනි.
C ++ වැඩිපුර පැටවීමට ඉඩ දී ඇති අතර C ට නොයන බොහෝ විශේෂාංග - පන්ති, සාමාජික කාර්යයන්, ව්යතිරේක පිරිවිතර වැනි - ක්රියාකාරී නාමය සංකේත නාමයක් ලෙස සරලව භාවිතා කළ නොහැක. එය විසඳීම සඳහා, C ++ ඊනියා නාම මැන්ග්ලිං භාවිතා කරයි, එමඟින් ක්රියාකාරී නාමය සහ අවශ්ය සියලු තොරතුරු (තර්කවල අංකය හා ප්රමාණය වැනි) සම්පාදකයා සහ සම්බන්ධකය විසින් පමණක් සකසන ලද අමුතු පෙනුමක් ඇති නූල් බවට පරිවර්තනය කරයි.
එබැවින් ඔබ බාහිර C ලෙස ශ්රිතයක් නියම කරන්නේ නම්, සම්පාදකයා එය සමඟ නම හැසිරවීම සිදු නොකරන අතර එහි සංකේත නාමය ශ්රිත නාමය ලෙස සෘජුවම ප්රවේශ කළ හැකිය.
එවැනි කාර්යයන් භාවිතා කිරීමේදී dlsym()
සහ ඇමතීමේදී මෙය ප්රයෝජනවත් dlopen()
වේ.
බොහෝ ක්රමලේඛන භාෂාවන් දැනට පවතින ක්රමලේඛන භාෂාවන් මත ගොඩනගා නොමැත. C ++ සෑදී ඇත්තේ C ට ඉහළින් වන අතර තව දුරටත් එය ක්රියාපටිපාටි ක්රමලේඛන භාෂාවකින් සාදන ලද වස්තු-නැඹුරු ක්රමලේඛන භාෂාවකි. එම හේතුව නිසා C ++ ප්රකාශන C extern "C"
සමඟ පසුගාමී අනුකූලතාවයක් සපයයි.
පහත උදාහරණය දෙස බලමු:
#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;
}
AC සම්පාදකයා ඉහත උදාහරණය සම්පාදනය නොකරනු ඇත, මන්ද එකම ශ්රිතය printMe
දෙවරක් අර්ථ දක්වා ඇත (ඒවාට int a
එදිරිව විවිධ පරාමිතීන් තිබුණද char a
).
gcc -o printMe printMe.c && ./printMe;
1 දෝෂයකි. PrintMe එක වරකට වඩා අර්ථ දක්වා ඇත.
C ++ සම්පාදකයෙකු ඉහත උදාහරණය සම්පාදනය කරයි. එය printMe
දෙවරක් අර්ථ දක්වා ඇති බවක් ගණන් ගන්නේ නැත .
g ++ -o printMe printMe.c && ./printMe;
මෙයට හේතුව C ++ සම්පාදකයෙකු ඒවායේ පරාමිතීන් මත පදනම්ව ව්යංගයෙන් ( මැංගල්ස් ) ක්රියා කරන බවයි. C හි, මෙම අංගයට සහය නොදක්වයි. කෙසේ වෙතත්, C ++ C හරහා ගොඩනඟන විට, භාෂාව නිර්මාණය කර ඇත්තේ වස්තු-නැඹුරු වන අතර, එකම නමේ ක්රම (ශ්රිත) සමඟ විවිධ පංති නිර්මාණය කිරීමේ හැකියාව සහ විවිධ මත පදනම්ව ක්රම ( ක්රම ඉක්මවා යාම ) අභිබවා යාමට අවශ්ය විය. පරාමිතීන්.
extern "C"
"සී ශ්රිත නාමයන් හසුරුවන්න එපා"කෙසේ වෙතත්, අපට "parent.c" නමින් පැරණි C ගොනුවක් ඇති බව සිතන්න, include
එය වෙනත් උරුම C ගොනු, "parent.h", "child.h" යනාදියෙහි ක්රියාකාරී නම් වේ. උරුමය "parent.c" ගොනුව ක්රියාත්මක වන්නේ නම් C ++ සම්පාදකයෙකු හරහා, එවිට ශ්රිත නාමයන් හසුරුවනු ඇති අතර, ඒවා තවදුරටත් "parent.h", "child.h" යනාදියෙහි දක්වා ඇති ක්රියාකාරී නම් සමඟ නොගැලපේ - එබැවින් එම බාහිර ලිපිගොනු වල ක්රියාකාරී නම් ද අවශ්ය වේ. අඹරන්න. සංකීර්ණ සී වැඩසටහනක් හරහා ක්රියාකාරී නාමයන් ඇලවීම, බොහෝ පරායත්තතා ඇති අය, බිඳුණු කේතයකට තුඩු දිය හැකිය; එබැවින් C ++ සම්පාදකයාට ක්රියාකාරී නාමයක් හසුරුවන්න එපා යැයි පැවසිය හැකි යතුරු පදයක් සැපයීම පහසු විය හැකිය.
මෙම extern "C"
මූල පදය නොවන mangle (ප්රතිනම්කෙරුම්) සී කාර්යය නම් කිරීමට C ++ compiler කියයි.
උදාහරණයක් වශයෙන්:
extern "C" void printMe(int a);
extern "C"
තිබේ නම් අපට භාවිතා කළ dll
නොහැකිද? මම අදහස් කළේ අපට ශීර්ෂ ගොනුවක් නොමැති නම් සහ ප්රභව ගොනුවක් (ක්රියාත්මක කිරීම් පමණක්) තිබේ නම් සහ එහි ක්රියාකාරීත්වය ශ්රිත දර්ශකය හරහා භාවිතා කිරීමයි. මෙම තත්වය තුළ, අපි කාර්යයන් භාවිතා කළෙමු (එහි නම නොසලකා).
බාහිර "C" වලින් ඔතා ඕනෑම C- ශීර්ෂයක් C ++ සමඟ අනුකූල විය නොහැක. C ++ මූල පද සමඟ C-header ගැටුමක හඳුනාගැනීම් C ++ සම්පාදකයා මේ ගැන පැමිණිලි කරනු ඇත.
උදාහරණයක් ලෙස, g ++ හි පහත කේතය අසමත් වන බව මම දැක ඇත්තෙමි:
extern "C" {
struct method {
int virtual;
};
}
Kinda තේරුමක් ඇති නමුත් C ++ වෙත C කේතය වරාය කිරීමේදී මතක තබා ගත යුතු දෙයකි.
extern "C"
වෙනත් පිළිතුරු වලින් විස්තර කර ඇති පරිදි සී සම්බන්ධතාවය භාවිතා කිරීම යන්නෙන් අදහස් කෙරේ. "අන්තර්ගතය සී ලෙස සම්පාදනය කිරීම" හෝ කිසිවක් අදහස් නොකෙරේ. int virtual;
C ++ හි වලංගු නොවන අතර විවිධ සම්බන්ධතා සඳහන් කිරීමෙන් එය වෙනස් නොවේ.
එය ශ්රිතයේ සම්බන්ධතාවය සී වෙතින් කැඳවිය හැකි ආකාරයට වෙනස් කරයි. ප්රායෝගිකව එයින් අදහස් වන්නේ ශ්රිත නාමය අක්රීය නොවන බවයි.
undname
.
සම්බන්ධ වන විට C හා C ++ වලින් සම්පාදනය කරන ලද ශ්රිතයන්ගේ නම් වෙනස් වන බැවින් එය C ++ සම්පාදකයාට C- ශෛලියක් තුළ සොයා බැලීමට දැනුම් දෙයි.
extern "C"
යනු Cpp ප්රභව ලිපිගොනු වල C ශ්රිත ඇමතීමට භාවිතා කරන සම්බන්ධක පිරිවිතරයකි . අපට C ශ්රිත ඇමතිය හැකිය , විචල්යතා ලිවිය හැකිය, සහ ශීර්ෂ ඇතුළත් කළ හැකිය. කාර්යය බාහිර වස්තුවෙන් ප්රකාශයට පත් කරන අතර එය පිටත අර්ථ දක්වා ඇත. සින්ටැක්ස් වේ
1 වර්ගය:
extern "language" function-prototype
2 වර්ගය:
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 <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);
}
exe
#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);
}
extern "C"
හා __declspec(dllexport)
සම්බන්ධයක් නැති වේ. කලින් පාලනය කළ සංකේත සැරසිලි, දෙවැන්න අපනයන ප්රවේශයක් නිර්මාණය කිරීමේ වගකීම දරයි. ඔබට C ++ නාම සැරසිලි භාවිතයෙන් සංකේතයක් අපනයනය කළ හැකිය. මෙම ප්රශ්නයේ කාරණය මුළුමනින්ම මග හැරී ඇතිවාට අමතරව, කේත නියැදියේ වෙනත් වැරදි ද තිබේ. එකක් නම්, main
ඔබේ ඩීඑල්එල් වෙතින් අපනයනය කළ ප්රතිලාභ ප්රතිලාභයක් ප්රකාශ නොකරයි. නැතහොත් සමුළුව කැඳවීම, ඒ සඳහා. ආයාත කරන විට, ඔබ අහඹු ඇමතුම් සම්මුතියක් ( WINAPI
) ආරෝපණය කරන අතර , බිට් 32 ගොඩනැගීම සඳහා වැරදි සංකේතය භාවිතා කරන්න (විය යුතුය _main
හෝ විය යුතුය _main@0
). කණගාටුයි, -1.
void*
, නමුත් ඔබේ ක්රියාත්මක කිරීම කිසිවක් ආපසු ලබා නොදේ. එය ඉතා හොඳින් පියාසර කරනු ඇත ...
මෙම පිළිතුර නොඉවසිලිමත් / හමුවීමට නියමිත දින නියමයන් ඇත, පහත දැක්වෙන්නේ කොටසක් / සරල පැහැදිලි කිරීමක් පමණි:
එබැවින්
C ++ හි, නම මැන්ග්ලිං සමඟ
C හි එක් එක් ශ්රිතය අද්විතීය ලෙස හඳුනා ගනී, නම මැන්ග්ලිං නොමැතිව පවා එක් එක් ශ්රිතය අද්විතීය ලෙස හඳුනා ගනී
C ++ හි හැසිරීම වෙනස් කිරීම සඳහා, එනම්, විශේෂිත ශ්රිතයක් සඳහා මැන්ග්ලිං සිදු නොවිය යුතු බව සඳහන් කිරීමට, ශ්රිත නාමයට පෙර බාහිර "C" භාවිතා කළ හැකිය , කුමන හේතුවක් නිසා හෝ dll වෙතින් නිශ්චිත නමක් සහිත ශ්රිතයක් අපනයනය කිරීම වැනි , එහි සේවාදායකයින්ගේ භාවිතය සඳහා.
වඩාත් සවිස්තරාත්මක / වඩාත් නිවැරදි පිළිතුරු සඳහා වෙනත් පිළිතුරු කියවන්න.
C සහ C ++ මිශ්ර කරන විට (එනම්, C ++ වෙතින් C ශ්රිතය ඇමතීම; සහ b. C වෙතින් C ++ ශ්රිතය ඇමතීම), C ++ නාම මැන්ග්ලිං සම්බන්ධ කිරීමේ ගැටළු ඇති කරයි. තාක්ෂණික වශයෙන් ගත් කල, මෙම ගැටළුව සිදුවන්නේ අනුරූප සම්පාදකයා භාවිතා කරමින් ඇමතුම් ශ්රිත දැනටමත් ද්විමය (බොහෝ විට * .a පුස්තකාල ගොනුවකට) සම්පාදනය කර ඇති විට පමණි.
එබැවින් C ++ හි මැන්ග්ලිං යන නම අක්රීය කිරීමට බාහිර "සී" භාවිතා කළ යුතුය.
වෙනත් හොඳ පිළිතුරු සමඟ ගැටීමෙන් තොරව, මම මගේ ආදර්ශය ටිකක් එකතු කරමි.
හරියටම C ++ සම්පාදකයා කරන්නේ කුමක්ද: එය සම්පාදන ක්රියාවලියේ නම් හසුරුවයි, එබැවින් ක්රියාත්මක කිරීමට විශේෂයෙන් සැලකීමට සම්පාදකයාට පැවසීම අවශ්ය වේ C
.
අපි C ++ පන්ති සාදා එකතු කරන විට extern "C"
, අපි C ඇමතුම් සම්මුතිය භාවිතා කරන බව අපගේ C ++ සම්පාදකයාට කියමු.
හේතුව (අපි C ++ සිට C ක්රියාත්මක කිරීම ලෙස හඳුන්වන්නෙමු ): එක්කෝ අපට C ++ වෙතින් C ශ්රිතය ඇමතීමට හෝ C වෙතින් C ++ ශ්රිතය ඇමතීමට අවශ්ය වේ (C ++ පන්ති ... ආදිය C හි ක්රියා නොකරයි).
සී සම්පාදකයෙකු විසින් සම්පාදනය කරන ලද ශ්රිත අවලංගු f () සහ සී ++ සම්පාදකයෙකු විසින් සම්පාදනය කරන ලද එකම නම සහිත ශුන්ය f () ශ්රිතයක් එකම ශ්රිතයක් නොවේ. ඔබ එම ශ්රිතය C හි ලියා, පසුව ඔබ එය C ++ වෙතින් ඇමතීමට උත්සාහ කළේ නම්, සම්බන්ධකය C ++ ශ්රිතය සොයනු ඇති අතර C ශ්රිතය සොයා නොගනී.
බාහිර "සී" සී ++ සම්පාදකයාට පවසන්නේ ඔබට සී සම්පාදකයා විසින් සම්පාදනය කරන ලද ශ්රිතයක් ඇති බවයි. එය සී සම්පාදකයා විසින් සම්පාදනය කළ බව ඔබ පැවසීමෙන් පසු, සී ++ සම්පාදකයා එය නිවැරදිව අමතන්නේ කෙසේදැයි දැන ගනු ඇත.
එය C ++ සම්පාදකයාට C ++ ශ්රිතයක් සම්පාදනය කිරීමට ඉඩ සලසයි. එම ශ්රිතය නිල වශයෙන් C ශ්රිතයක් වනු ඇත, නමුත් එය C ++ සම්පාදකයා විසින් සම්පාදනය කර ඇති බැවින්, එයට සියලු C ++ විශේෂාංග භාවිතා කළ හැකි අතර සියලු C ++ මූල පද ඇත.
extern "C"
ශ්රිතයක් සම්පාදනය කළ හැකිය - සහ (සමහර සීමාවන්ට යටත්ව) එය C සම්පාදකයෙකු විසින් සම්පාදනය කරන ලද කේතයෙන් කැඳවිය හැක.