extern "C"
সি ++ কোডে ঠিক কী করা যায়?
উদাহরণ স্বরূপ:
extern "C" {
void foo();
}
foo()
ফাংশন রয়েছে।
extern "C"
সি ++ কোডে ঠিক কী করা যায়?
উদাহরণ স্বরূপ:
extern "C" {
void foo();
}
foo()
ফাংশন রয়েছে।
উত্তর:
বাহ্যিক "সি" সি ++ এ একটি ফাংশন-নাম তৈরি করে 'সি' লিঙ্কেজ রয়েছে (সংকলক নামটি ছাঁটাই করে না) যাতে ক্লায়েন্ট সি কোডটি একটি 'সি' সামঞ্জস্যপূর্ণ শিরোলেখ ফাইলটি ব্যবহার করে আপনার ফাংশনটিতে লিঙ্ক করতে পারে (যেমন ব্যবহার করতে পারে) যা কেবলমাত্র আপনার ফাংশন ঘোষণা। আপনার ফাংশন সংজ্ঞাটি একটি বাইনারি বিন্যাসে অন্তর্ভুক্ত রয়েছে (এটি আপনার সি ++ সংকলক দ্বারা সংকলিত হয়েছিল) যে ক্লায়েন্ট 'সি' লিঙ্কার তারপরে 'সি' নামটি ব্যবহার করে লিঙ্ক করবে।
যেহেতু সি ++ এর ক্রিয়াকলাপের নামগুলি ওভারলোডিং রয়েছে এবং সি নেই, তাই সি ++ সংকলকটি লিঙ্ক করতে কেবল ফাংশনটির নামটি অনন্য আইডি হিসাবে ব্যবহার করতে পারে না, সুতরাং এটি যুক্তি সম্পর্কিত তথ্য যুক্ত করে নামটিকে মঙ্গল করে। এসি সংকলকটির নামটি ম্যাঙ্গেল করার দরকার নেই যেহেতু আপনি সি তে ফাংশন নামগুলি ওভারলোড করতে পারবেন না যখন আপনি যখন বলেন যে কোনও ফাংশনে সি ++ এর বহিরাগত "সি" লিঙ্ক রয়েছে, সি ++ সংকলকটির জন্য ব্যবহৃত নামের সাথে যুক্তি / প্যারামিটার ধরণের তথ্য যুক্ত করে না দুটো ঘটনার।
কেবলমাত্র আপনি জানেন, আপনি প্রতিটি পৃথক ঘোষণা / সংজ্ঞা স্পষ্টভাবে "সি" লিঙ্কেজ নির্দিষ্ট করতে পারেন বা নির্দিষ্ট লিঙ্কেজের জন্য ঘোষণাগুলি / সংজ্ঞাগুলির ক্রমকে গ্রুপ করতে ব্লক ব্যবহার করতে পারেন:
extern "C" void foo(int);
extern "C"
{
void g(char);
int i;
}
আপনি যদি প্রযুক্তিগুলির বিষয়ে যত্নশীল হন তবে সেগুলি C ++ 03 স্ট্যান্ডার্ডের 7.5 বিভাগে তালিকাভুক্ত করা হয়েছে, এখানে একটি সংক্ষিপ্ত সারাংশ দেওয়া হয়েছে (বাহ্যিক "সি" তে জোর দিয়ে):
extern "C" { int i; }
একটি সংজ্ঞা। এটি আপনি নির্ধারিত সংজ্ঞা ছাড়াই নাও করতে পারেন void g(char);
। এটি একটি সংজ্ঞা হিসাবে তৈরি করতে আপনার প্রয়োজন হবে extern "C" { extern int i; }
। অন্যদিকে, ধনুর্বন্ধনী ছাড়া এক-ঘোষণা সিনট্যাক্স ঘোষণা একটি অ-সংজ্ঞা বর্ননা করেন, extern "C" int i;
হিসাবে একইextern "C" { extern int i; }
আমি কিছুটা তথ্য যুক্ত করতে চেয়েছিলাম, যেহেতু এটি এখনও পোস্ট করা হয়নি।
আপনি প্রায়শই সি এর শিরোনামে কোড দেখতে পাবেন:
#ifdef __cplusplus
extern "C" {
#endif
// all of your legacy C code here
#ifdef __cplusplus
}
#endif
এটি যা অর্জন করে তা হ'ল এটি আপনাকে সেই সি হেডার ফাইলটি আপনার সি ++ কোডের সাথে ব্যবহার করতে দেয়, কারণ ম্যাক্রো "__cplusplus" সংজ্ঞায়িত করা হবে। কিন্তু আপনি করতে পারেন এছাড়াও এখনও আপনার উত্তরাধিকার সি কোড, যেখানে ম্যাক্রো সঙ্গে এটি ব্যবহার না সংজ্ঞায়িত, তাই এটি স্বতন্ত্র সি ++ কনস্ট্রাক্ট দেখতে পাবেন না।
যদিও, আমি সি ++ কোডও দেখেছি যেমন:
extern "C" {
#include "legacy_C_header.h"
}
যা আমি কল্পনা করি একই জিনিসটি সফল করে তোলে।
কোন উপায়টি ভাল তা নিশ্চিত নয়, তবে আমি উভয়ই দেখেছি।
extern "C"
শিরোনামে দেখেছিল )। এটি দুর্দান্ত কাজ করে, এই কৌশলটি বহুবার ব্যবহার করে।
extern "C"
অন্তর্ভুক্ত হওয়ার আগে বা পরে এটির মুখোমুখি হয় কিনা তা কম যত্ন নিতে পারে না । সংকলকটি পৌঁছানোর সময়, এটি যাইহোক প্রিপ্রোসেসড পাঠ্যের কেবল একটি দীর্ঘ স্ট্রিম।
g++
কমপক্ষে গত ১ years বছরে যে কোনও সময় কোনও লক্ষ্য হিসাবে এটির কোনও সংস্করণ পাওয়া যায় নি wrong প্রথম উদাহরণটির পুরো বিষয়টি হ'ল আপনি সি বা সি ++ সংকলক ব্যবহার করেন কিনা তা বিবেচ্য নয়, 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
যে জিনিসগুলি বহিরাগত সি তে কাজ করে না
এটি সুস্পষ্ট হয়ে যায় যে যে কোনও সি ++ বৈশিষ্ট্য যাতে নাম ম্যাংলিংয়ের প্রয়োজন হয় তা ভিতরে কাজ করবে না 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) { }
}
সি ++ উদাহরণ থেকে ন্যূনতম চলমান সি
সম্পূর্ণতার স্বার্থে এবং সেখানে নতুনদের জন্য, আরও দেখুন: একটি সি ++ প্রকল্পে সি উত্স ফাইলগুলি কীভাবে ব্যবহার করবেন?
সি ++ থেকে সি কল করা বেশ সহজ: প্রতিটি সি ফাংশনে কেবল একটি সম্ভাব্য অ-মাংগেল্ড প্রতীক থাকে, সুতরাং অতিরিক্ত কোনও কাজের প্রয়োজন হয় না।
main.cpp
#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
extern "C"
লিঙ্ক ব্যতীত ব্যর্থ:
main.cpp:6: undefined reference to `f()'
কারণ g++
একটি ম্যাঙ্গলেড f
, যা gcc
উত্পাদন করেনি খুঁজে প্রত্যাশা করে।
সি উদাহরণ থেকে ন্যূনতম চলমান সি ++
সি থেকে সি ++ কল করা কিছুটা শক্ত: আমাদের প্রতিটি ফাংশন ম্যানুয়ালি তৈরি করতে হবে যা আমরা প্রকাশ করতে চাই।
এখানে আমরা চিত্রিত করি যে কীভাবে সি ++ ফাংশন ওভারলোডগুলি সি তে প্রকাশ করা যায় to
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) কারণ আপনি পৃথক পৃথক উদাহরণ দেখান প্রতিটি। ধন্যবাদ!
প্রতিটি সি ++ প্রোগ্রামে, সমস্ত অ স্থিত ফাংশনগুলি বাইনারি ফাইলটিতে প্রতীক হিসাবে প্রদর্শিত হয় represented এই চিহ্নগুলি বিশেষ পাঠ্যের স্ট্রিং যা প্রোগ্রামের কোনও ক্রিয়াকে অনন্যভাবে চিহ্নিত করে।
সি-তে, চিহ্নটির নামটি ফাংশন নামের মতো। এটি সম্ভব কারণ সি তে কোনও দুটি অ স্থির ফাংশনের একই নাম থাকতে পারে না।
কারণ সি ++ ওভারলোডিংকে মঞ্জুরি দেয় এবং এমন অনেকগুলি বৈশিষ্ট্য রয়েছে যা সি দেয় না - যেমন ক্লাস, সদস্য ফাংশন, ব্যতিক্রমের বিবরণ - এটি কেবলমাত্র প্রতীক নাম হিসাবে ফাংশনটির নাম ব্যবহার করা সম্ভব নয়। এটি সমাধানের জন্য, সি ++ তথাকথিত নাম ম্যাংলিং ব্যবহার করে, যা ফাংশনটির নাম এবং সমস্ত প্রয়োজনীয় তথ্য (যুক্তিগুলির সংখ্যা এবং আকারের মতো) কেবলমাত্র সংকলক এবং লিঙ্কার দ্বারা প্রক্রিয়াকৃত কিছু অদ্ভুত চেহারাযুক্ত স্ট্রিংয়ে রূপান্তর করে।
সুতরাং আপনি যদি কোনও ফাংশন বহিরাগত সি হিসাবে নির্দিষ্ট করেন তবে সংকলকটি এর সাথে নাম ম্যাংলিং সম্পাদন করে না এবং এটির ফাংশন নাম হিসাবে এটির প্রতীক নামটি ব্যবহার করে সরাসরি অ্যাক্সেস করা যায়।
ব্যবহার করার সময় dlsym()
এবং dlopen()
এই জাতীয় ফাংশন কল করার জন্য এটি কার্যকর হয়।
বেশিরভাগ প্রোগ্রামিং ভাষা বিদ্যমান প্রোগ্রামিং ভাষার উপরে নির্মিত হয় না। সি ++ সি এর শীর্ষে নির্মিত হয় এবং তদ্ব্যতীত এটি প্রক্রিয়াগত প্রোগ্রামিং ভাষা থেকে নির্মিত একটি অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং ভাষা এবং সেই কারণে সি ++ এর মত প্রকাশ রয়েছে extern "C"
যা সি এর সাথে পিছনের দিকে সামঞ্জস্যতা সরবরাহ করে provide
আসুন নীচের উদাহরণটি দেখুন:
#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;
}
এসি সংকলক উপরের উদাহরণটি সংকলন করবে না, কারণ একই ফাংশনটি printMe
দু'বার সংজ্ঞায়িত হয়েছে (যদিও তাদের বিভিন্ন পরামিতি int a
বনাম রয়েছে char a
)।
gcc -o printMe printMe.c &&//PritMe;
1 ত্রুটি মুদ্রণটি একাধিকবার সংজ্ঞায়িত হয়।
একটি সি ++ সংকলক উপরের উদাহরণটি সংকলন করবে। এটি যত্ন করে না যে printMe
দুবার সংজ্ঞায়িত হয়েছে।
g ++ -o মুদ্রণমাধ্যমে মুদ্রণপ্রেম && ./printMe;
এটি কারণ যে কোনও সি ++ সংকলক তাদের পরামিতিগুলির উপর ভিত্তি করে অন্তর্নিহিতভাবে ফাংশনগুলির নাম ( মঙ্গলগুলি ) দেয়। সি তে, এই বৈশিষ্ট্যটি সমর্থিত ছিল না। যাইহোক, যখন সি ++ সি এর উপরে নির্মিত হয়েছিল, তখন ভাষাটি অবজেক্ট-ওরিয়েন্টেড, এবং একই নামের পদ্ধতিগুলি (ফাংশন) সহ বিভিন্ন শ্রেণি তৈরি করার ক্ষমতা এবং বিভিন্ন ভিত্তিতে পদ্ধতিগুলি ( মেথার ওভাররাইডিং ) ওভাররাইড করার জন্য সমর্থন করার প্রয়োজন হয়েছিল প্যারামিটার।
extern "C"
"সি সি ফাংশন নামগুলি ম্যাঙ্গেল করবেন না" বলেযাইহোক, কল্পনা করুন যে আমাদের কাছে একটি "লিগ্যাসি সি ফাইল আছে" নামক "প্যারেন্ট.সি" রয়েছে যা include
অন্য লিগ্যাসি সি ফাইলগুলি থেকে "প্যারেন্ট এইচ", "চাইল্ড এইচ" ইত্যাদি নামগুলি ব্যবহার করে যদি লিগ্যাসি "প্যারেন্ট.সি" ফাইলটি চালানো হয় If সি ++ কম্পাইলারের মাধ্যমে ফাংশনটির নামগুলি ম্যাঙ্গেল করা হবে এবং তারা আর "প্যারেন্ট এইচ", "চাইল্ড এইচ", ইত্যাদিতে নির্দিষ্ট ফাংশনের নামের সাথে মেলে না - সুতরাং এই বাহ্যিক ফাইলগুলিতে ফাংশনের নামগুলিও প্রয়োজন হবে মাংগাল করা। একটি জটিল সি প্রোগ্রাম জুড়ে ম্যানলিং ফাংশনগুলির নামগুলি, প্রচুর নির্ভরশীলতা সহ, ভাঙা কোডের দিকে নিয়ে যেতে পারে; সুতরাং এমন কীওয়ার্ড সরবরাহ করা সুবিধাজনক হতে পারে যা সি ++ সংকলককে কোনও ফাংশনের নাম ম্যাঙ্গেল না করতে বলতে পারে।
extern "C"
শব্দ একটি সি ++ কম্পাইলার বলে করতে ছিন্ন করা (রিনেম) সি ক্রিয়াটি নাম থাকবে না।
উদাহরণ স্বরূপ:
extern "C" void printMe(int a);
extern "C"
আমাদের যদি কেবল একটি dll
ফাইল থাকে তবে আমরা কী তা ব্যবহার করতে পারি না ? আমি বলতে চাইছি যদি আমাদের কাছে কোনও শিরোনাম ফাইল না থাকে এবং কেবল একটি উত্স ফাইল থাকে (কেবল বাস্তবায়ন) এবং ফাংশন পয়েন্টারের মাধ্যমে এর ফাংশনটি ব্যবহার করে। এই অবস্থায় আমরা কেবল ফাংশন ব্যবহার করি (এর নাম নির্বিশেষে)।
কোনও সি-শিরোনামকে কেবলমাত্র বাহ্যিক "সি" এ মোড়ানো দ্বারা সি ++ এর সাথে সামঞ্জস্য করা যায় না। সি-শিরোনামে শনাক্তকারীরা যখন C ++ কীওয়ার্ডগুলির সাথে দ্বন্দ্ব করেন তখন সি ++ সংকলক এ সম্পর্কে অভিযোগ করবেন।
উদাহরণস্বরূপ, আমি নীচের কোডটি জি ++ এ ব্যর্থ দেখেছি:
extern "C" {
struct method {
int virtual;
};
}
কিন্ডা বোঝায়, কিন্তু সি-কোডটি সি ++ তে পোর্ট করার সময় মনে রাখার মতো কিছু।
extern "C"
অন্যান্য উত্তর দ্বারা বর্ণিত হিসাবে সি লিঙ্কেজ ব্যবহার করার অর্থ। এর অর্থ এই নয় যে "সামগ্রীগুলি সি হিসাবে সংকলন করুন" বা যে কোনও কিছুই anything int virtual;
সি ++ এ অবৈধ এবং বিভিন্ন লিঙ্কেজ নির্দিষ্ট করে তা পরিবর্তন করে না।
এটি কোনও ফাংশনটির সংযোগটি এমনভাবে পরিবর্তন করে যে ফাংশনটি সি থেকে কলযোগ্য হয় অনুশীলনে এর অর্থ হল যে ফাংশনটির নাম ম্যাঙ্গেলড নয় ।
undname
।
লিঙ্ক করার সময় সি-স্টাইলে those ফাংশনগুলির নাম সন্ধান করতে এটি সি ++ সংকলককে অবহিত করে, কারণ লিঙ্কিংয়ের পর্যায়ে সি এবং সি ++ তে সংকলিত ফাংশনগুলির নাম পৃথক।
আমি dll (ডায়নামিক লিংক লাইব্রেরি) ফাইলগুলি আগে প্রধান () ফাংশনটিকে "রফতানযোগ্য" তৈরি করতে আগে 'বাহ্যিক "সি" ব্যবহার করেছি যাতে এটি পরে dll থেকে অন্য নির্বাহযোগ্য ক্ষেত্রে ব্যবহার করা যায়। আমি যেখানে এটি ব্যবহার করতাম তার উদাহরণ কার্যকর হতে পারে।
ডিএলএল
#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)
সম্পর্কযুক্ত নয়। প্রাক্তন নিয়ন্ত্রণ প্রতীক সজ্জা, দ্বিতীয়টি রফতানি এন্ট্রি তৈরির জন্য দায়ী। আপনি সি ++ নাম সজ্জা ব্যবহার করে একটি চিহ্নও রফতানি করতে পারেন। এই প্রশ্নের বিন্দুটি পুরোপুরি অনুপস্থিত ছাড়াও কোড নমুনায় অন্যান্য ভুল রয়েছে। একটির জন্য, main
আপনার ডিএলএল থেকে রফতানি কোনও ফেরতের মান ঘোষণা করে না। বা কনভেনশন আহ্বান, এই বিষয়ে। আমদানি করার সময়, আপনি একটি এলোমেলো কলিং কনভেনশন ( WINAPI
) বৈশিষ্ট্যযুক্ত করেন , এবং 32-বিট বিল্ডগুলির জন্য ভুল প্রতীক ব্যবহার করেন (হওয়া উচিত _main
বা _main@0
)। দুঃখিত, -1।
void*
তবে আপনার বাস্তবায়ন কিছুই ফেরায় না। এটি সত্যিই ভাল উড়ে যাবে ...
extern "C"
একটি দুটো ঘটনার স্পেসিফিকেশন যা ব্যবহার করা হয় সি ফাংশান কল মধ্যে CPP সোর্স ফাইল । আমরা সি ফাংশনগুলি কল করতে পারি , ভেরিয়েবলগুলি লিখতে পারি এবং শিরোনাম অন্তর্ভুক্ত করতে পারি । বাহ্যিক সত্তায় ফাংশন ঘোষণা করা হয় এবং এটি বাইরে সংজ্ঞায়িত করা হয়। সিনট্যাক্স হয়
ধরন 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)
{
//
//
}
এই উত্তরটি অধৈর্য / পূরণের সময়সীমার জন্য, কেবল একটি অংশ / সাধারণ ব্যাখ্যা নীচে:
তাই
সি ++ নাম mangling সঙ্গে প্রতিটি ফাংশন পরিচয়
সি, এমনকি নাম স্বতন্ত্র mangling ছাড়া প্রতিটি ফাংশন পরিচয়
সি ++ এর আচরণ পরিবর্তন করার জন্য, নির্দিষ্ট নামটির জন্য ম্যাংলিংটি নির্দিষ্ট ক্রিয়াকলাপের জন্য হওয়া উচিত নয় তা নির্দিষ্ট করতে আপনি যে কোনও কারণেই ডান থেকে নির্দিষ্ট নামের সাথে ফাংশন রফতানির মতো ফাংশনের নামের আগে বহিরাগত "সি" ব্যবহার করতে পারেন , এর ক্লায়েন্টদের ব্যবহারের জন্য।
আরও বিস্তারিত / আরও সঠিক উত্তরের জন্য অন্যান্য উত্তরগুলি পড়ুন।
সি এবং সি ++ (অর্থাত্, সি .+ থেকে কলিং সি ফাংশন; এবং সি থেকে সি ++ ফাংশন কল করা) মিশ্রণের সময়, সি ++ নাম মংলিং লিঙ্কিংয়ের সমস্যা সৃষ্টি করে। প্রযুক্তিগতভাবে বলতে গেলে, এই সমস্যাটি কেবল তখনই ঘটে যখন কলি ফাংশনগুলি ইতিমধ্যে সম্পর্কিত সংকলকটি ব্যবহার করে বাইনারি (সম্ভবত একটি * .এ একটি লাইব্রেরী ফাইল) মধ্যে সংকলন করা হয়েছে।
সুতরাং আমাদের C ++ এ ম্যাংলিং নামটি অক্ষম করতে বহিরাগত "সি" ব্যবহার করতে হবে।
অন্যান্য ভাল উত্তরের সাথে বিরোধ না করে আমি আমার উদাহরণের কিছুটা যোগ করব।
সি ++ কম্পাইলার হুবহু কী করে: এটি সংকলন প্রক্রিয়ায় নামগুলিকে ম্যাঙ্গেল করে, তাই আমাদের সংকলকটিকে চিকিত্সা করার জন্য বলার প্রয়োজন C
বাস্তবায়নের জন্য বিশেষভাবে ।
যখন আমরা সি ++ ক্লাস তৈরি করি এবং যুক্ত করি extern "C"
, তখন আমরা আমাদের সি ++ সংকলককে বলি যে আমরা সি কলিং কনভেনশনটি ব্যবহার করছি।
কারণ (আমরা সি ++ থেকে সি বাস্তবায়ন কল করছি): হয় আমরা সি ++ থেকে সি ফাংশন কল করতে চাই বা সি ++ ফাংশনটি সি থেকে কল করতে চাই (সি ++ ক্লাস ... ইত্যাদি সিতে কাজ করে না)।
সি সংকলক দ্বারা সংকলিত একটি ফাংশন অকার্যকর এফ () এবং সি ++ সংকলক দ্বারা সংকলিত একই নামের শূন্য ফ () সহ একটি ফাংশন একই ফাংশন নয়। আপনি যদি সেই ফাংশনটি সিটিতে লিখেছিলেন এবং তারপরে আপনি এটিকে C ++ থেকে কল করার চেষ্টা করেছিলেন, তবে লিঙ্কারটি সি ++ ফাংশনটি সন্ধান করবে এবং সি ফাংশনটি খুঁজে পাবে না।
বাহ্যিক "সি" সি ++ সংকলককে বলে যে আপনার একটি ফাংশন রয়েছে যা সি সংকলক দ্বারা সংকলিত হয়েছিল। একবার আপনি বলবেন যে এটি সি সংকলক দ্বারা সংকলিত হয়েছিল, সি ++ সংকলক এটি কীভাবে সঠিকভাবে কল করতে পারে তা জানতে পারবে।
এটি সি ++ সংকলককে একটি সি ++ ফাংশন এমনভাবে সংকলন করতে দেয় যাতে সি সংকলক এটি কল করতে পারে। এই ফাংশনটি আনুষ্ঠানিকভাবে একটি সি ফাংশন হবে তবে এটি যেহেতু এটি সি ++ সংকলক দ্বারা সংকলিত হয়েছে সেহেতু এটি সমস্ত সি ++ বৈশিষ্ট্য ব্যবহার করতে পারে এবং এতে সমস্ত সি ++ কীওয়ার্ড রয়েছে।
extern "C"
ফাংশন সংকলন করতে পারে - এবং (কিছু সীমাবদ্ধতার সাপেক্ষে) এটি সি সংকলক দ্বারা সংকলিত কোড দ্বারা কলযোগ্য হবে।