فراخوانی توابع سی ( c ) در سی پلاس پلاس (c++) در لینوکس
مقدمه:
گاهی از اوغات احتیاج داریم که از داخل برنامه c++ بعضی از توابع سی رو فراخوانی کنیم و یا اینکه سورسی داریم به زبان سی نوشته شده و ما مخواییم اونو توی c++ خودم استفاده کنیم! در اینجا یا باید کل سورس رو به به یبان مورد نظر تغییر بدیم یا اینکه از روش زیراستفاده کنیم!
انجام مراحل:
در لینوکس کتابخانههای اشتراکی داریم که میتونیم داخل برنامههامون ازشون استفاده کنیم؛
اگه بخوام مقایسهای داشته باشم میتونم بگم همانند dll در ویندوز که هر برنامهای میتونهای ازشون استفاده کنه؛ ما در لینوکس فایلهای اشتراکی داریم که با پسوند so شناخته میشوند!
پس مراحل کار همانند ساخت dll به این ترتیب هستش که
اول کدمون رو به فایل کتابخانهای تبدیل کنیم
دوم این فایل رو برناهامون استفاده کنیم
در اینجا میخواییم با زبان برنامه نویسی c یک تابع درست کنیم و اونو تبدیل به فایل کتابخانهای کنیم؛ و در c++ ازش استفاده کنیم؛
تمام این کارها رو با کمک کامپایلر قدرتمند gcc انجام میدیم!
سورس کد زیر رو در نظر بگیرید که احتیاج به توضیح نداره؛
نام فایل : Cfile.c
کد php:
#include <stdio.h>
void f(void)
{
printf("\n This is a C code\n");
}
دستور زیر رو اجرا میکنیم:
کد php:
$ gcc -c -Wall -Werror -fPIC Cfile.c
این دستور یک فایلی به نام Cfile.o رو تولید میکنه
( که البته میتونید با پارامتر o نام فایل خروجی رو هم تعیین کنید که من اینکارو نکردم)
و بعد دستور زیر رو اجرا میکنیم:
کد php:
$ gcc -shared -o libCfile.so Cfile.o
خروجی این دستور فایل کتابخانهای بنام libCfile.so هستش! (یعنی همون dll ساخته شد!)
به همین راحتی یک فایل کتابخانهای ساختیم که در این لحظه تنها کاری که باید انجام بدیم اینه که ازش استفاده کنیم!
هدفمون استفاده از داخل c++ هست:
کد زیر رو مینویسم:
(نام فایل main.cpp)
کد php:
#include <iostream>
extern "C" {
void f();
}
void func(void)
{
std::cout<<"\n being used within C++ code\n";
}
int main(void)
{
f();
func();
return 0;
}
توضیح برنامهی فوق:
تمام برنامه واستون آشناست احتمالا بجز قسمت زیر:
توسط این دستور به کامپایلر میگیم که میخواییم از یک تابع خارجی c استفاده کنیم
چون در حالت معمولی کامپایلر نمیدونه این تابع f چیه! امکان داره هشدار بده و یا خطا بگیره؛ اما توسط دستور بالا میگیم که ما میدونیم این تابع چیه؛ شما فقط کامپایل کن!
حالا نوبت میرسه به کامپایل این برنامه؛
کد php:
$ g++ -L/home/himanshu/practice/ -Wall main.cpp -o main -lCfile
چند نکته:
۱: پارامتر L تعیین میکنه که پوشهی فایل اشتراکیمون کجاست
۲:
سوال:
ما پوشه رو مشخص کردیم اما امکان داره ۱۰۰ تا فایل اشتراکی تی پوشه باشه! برنام از کجا میفهمه باید از کدوم استفاده کنه؟ ما که توی دستور بالا اسم فایل (libCfile.so) رو ننوشتیم!
جواب:
این یک نوع استانداره اسم گذاری فایلهای اشتراکیه که به این شکله libxxxx.so؛ اگه به کاموایلر فقط بگیم xxx خودش مفهمه که بهدفمون استفاده از libxxx.so هستش؛ پس نام فایل کتابخانهای که درست کردیم بودش libCfile.so که اگه با پارامتر l فقط بگیم Cfile خود کاموایلر میفهمه که باید از libCfile.so استفاده کنه! به همین خوشمزگی!!!
در این مرحله برناممون درست شده اما یک نکته کنکوری! که با مثال توضیح میدم!
توی ویندوز شما وقتی از dll استفاده میکنید؛ بعد از اجرای برنامه؛ خود برنامه یا توی درایو system میگرده دنبال این فایل dll یا توی پوشه جاری برنامه و یا ...
اما توی لینوکس تمام برنامه های توی پوشههایی که در متغیر محیطی LD_LIBRARY_PATH هستش دنبال این so میگرده! پس الا باید مسیری که این so رو درست کردیم رو داخل این متغیر بریزیم:
کد php:
$ export LD_LIBRARY_PATH=/home/himanshu/practice:$LD_LIBRARY_PATH
دیگه کار تمومه و باید اجراش کنیم:
کد php:
$ ./main
This is a C code
being used within C++ code
آموزش بعدی استفاده از توابع c++ در c هستش که میتونید از منبع هم آموزشو بخونید!
نمایش فیلم کارهایی که بالا ذکر کردم در لینوکس خودمان
منبع:
خودم
سایت