লিনাক্স ভাগ করে নেওয়া লাইব্রেরি ন্যূনতম চলমান API বনাম এবিআই উদাহরণ
এই উত্তরটি আমার অন্য উত্তর থেকে বের করা হয়েছে: অ্যাপ্লিকেশন বাইনারি ইন্টারফেস (এবিআই) কী? তবে আমি অনুভব করেছি যে এটি সরাসরি এর উত্তরও দেয় এবং প্রশ্নগুলি সদৃশ হয় না।
ভাগ করা লাইব্রেরিগুলির প্রসঙ্গে, "একটি স্থিতিশীল এবিআই থাকা" এর সর্বাধিক গুরুত্বপূর্ণ বিষয়টি হ'ল লাইব্রেরি পরিবর্তনের পরে আপনার প্রোগ্রামগুলি পুনরায় সংকলনের দরকার নেই।
যেমন আমরা নীচের উদাহরণে দেখব, এটিআইআই অপরিবর্তিত থাকলেও প্রোগ্রামগুলি ভঙ্গ করে এবিআইকে সংশোধন করা সম্ভব।
main.c
#include <assert.h>
#include <stdlib.h>
#include "mylib.h"
int main(void) {
mylib_mystrict *myobject = mylib_init(1);
assert(myobject->old_field == 1);
free(myobject);
return EXIT_SUCCESS;
}
mylib.c
#include <stdlib.h>
#include "mylib.h"
mylib_mystruct* mylib_init(int old_field) {
mylib_mystruct *myobject;
myobject = malloc(sizeof(mylib_mystruct));
myobject->old_field = old_field;
return myobject;
}
mylib.h
#ifndef MYLIB_H
#define MYLIB_H
typedef struct {
int old_field;
} mylib_mystruct;
mylib_mystruct* mylib_init(int old_field);
#endif
সংকলন এবং এর সাথে সূক্ষ্ম রান:
cc='gcc -pedantic-errors -std=c89 -Wall -Wextra'
$cc -fPIC -c -o mylib.o mylib.c
$cc -L . -shared -o libmylib.so mylib.o
$cc -L . -o main.out main.c -lmylib
LD_LIBRARY_PATH=. ./main.out
এখন, যে অনুমান গ্রন্থাগার এর v2 জন্য, আমরা একটি নতুন ক্ষেত্র যোগ করতে চান mylib_mystrict
নামক new_field
।
যদি আমরা ক্ষেত্রটি এর আগে old_field
হিসাবে যুক্ত করেছি:
typedef struct {
int new_field;
int old_field;
} mylib_mystruct;
এবং লাইব্রেরি পুনর্নির্মাণ কিন্তু না main.out
, তারপর জোর ব্যর্থ!
লাইনটি কারণ:
myobject->old_field == 1
int
কাঠামোর প্রথমটি অ্যাক্সেস করার চেষ্টা করছে এমন সমাবেশ তৈরি করেছে যা এখন new_field
প্রত্যাশার পরিবর্তে old_field
।
অতএব এই পরিবর্তনটি এবিআইকে ভেঙে দিয়েছে।
তবে, যদি আমরা new_field
পরে যুক্ত করি old_field
:
typedef struct {
int old_field;
int new_field;
} mylib_mystruct;
তারপরে পুরানো উত্পন্ন সমাবেশটি এখনও কাঠামোর প্রথমটিতে অ্যাক্সেস করে int
এবং প্রোগ্রামটি এখনও কাজ করে, কারণ আমরা এবিআইকে স্থিতিশীল রেখেছিলাম।
এখানে গিটহাবের উপর এই উদাহরণটির একটি সম্পূর্ণ স্বয়ংক্রিয় সংস্করণ ।
এই এবিআইকে স্থিতিশীল রাখার আরেকটি উপায় হ'ল অস্বচ্ছ স্ট্রাক্টmylib_mystruct
হিসাবে বিবেচনা করা এবং কেবল পদ্ধতি সহায়কগুলির মাধ্যমে তার ক্ষেত্রগুলি অ্যাক্সেস করা। এটি এবিআইকে স্থিতিশীল রাখা সহজ করে তোলে, তবে আমরা আরও ফাংশন কল করতে চাইলে ওভারহেডের পারফরম্যান্স পড়তে পারে।
এপিআই বনাম এবিআই
পূর্ববর্তী উদাহরণে, এটা খেয়াল করা জরুরী যে যোগ আকর্ষণীয় new_field
সামনে old_field
, শুধুমাত্র ABI- র কপর্দকশূন্য, কিন্তু না API- টি।
এর অর্থ কী, এটি যদি আমরা আমাদের সংশোধন করতাম main.c
গ্রন্থাগারের বিরুদ্ধে প্রোগ্রামটি করি তবে তা নির্বিশেষে কাজ করতে পারত।
আমরা উদাহরণস্বরূপ ফাংশনের স্বাক্ষর বদলে থাকলে আমরা এপিআইও ভেঙে দিতাম:
mylib_mystruct* mylib_init(int old_field, int new_field);
যেহেতু, main.c
সম্পূর্ণ সংকলন বন্ধ হবে।
সিনেটিক এপিআই বনাম প্রোগ্রামিং এপিআই বনাম এবিআই
আমরা তৃতীয় ধরণের এপিআই পরিবর্তনগুলিকে শ্রেণিবদ্ধ করতে পারি: অর্থগত পরিবর্তন।
উদাহরণস্বরূপ, যদি আমরা সংশোধন করেছিলাম
myobject->old_field = old_field;
প্রতি:
myobject->old_field = old_field + 1;
তারপরে এটি এপিআই বা এবিআই কে না ভেঙে ফেলত, main.c
তবুও ভেঙে যেত!
এটি কারণ আমরা প্রোগ্রামগতভাবে লক্ষণীয় দিকের চেয়ে ফাংশনটি করার কথা বলে তার "মানবিক বিবরণ" পরিবর্তন করেছি।
আমার সবেমাত্র দার্শনিক অন্তর্দৃষ্টি ছিল যে সফ্টওয়্যারটির আনুষ্ঠানিক যাচাইকরণ একটি অর্থে "শব্দার্থক এপিআই" এর আরও অনেককে "প্রোগ্রামালিফিকেশন যাচাইযোগ্য এপিআই" তে স্থানান্তরিত করে।
সিমেটিক এপিআই বনাম প্রোগ্রামিং এপিআই
আমরা তৃতীয় ধরণের এপিআই পরিবর্তনগুলিকে শ্রেণিবদ্ধ করতে পারি: অর্থগত পরিবর্তন।
শব্দার্থক এপিআই, সাধারণত এপিআই ডকুমেন্টেশনের মধ্যে অন্তর্ভুক্ত করা হয়, এপিআই কী করা উচিত তার একটি প্রাকৃতিক ভাষার বিবরণ।
সুতরাং প্রোগ্রামটি নিজেই বিল্ড না করেই সিমেটিক এপিআই ভাঙ্গা সম্ভব।
উদাহরণস্বরূপ, যদি আমরা সংশোধন করেছিলাম
myobject->old_field = old_field;
প্রতি:
myobject->old_field = old_field + 1;
তাহলে এটি প্রোগ্রামিং এপিআই, না এবিআই, না ভেঙে যাবে main.c
সিমেটিক এপিআই ভেঙে যাবে।
প্রোগ্রামটিমেটিকভাবে চুক্তি এপিআই চেক করার দুটি উপায় রয়েছে:
- একগুচ্ছ কোণার কেস পরীক্ষা করুন। করা সহজ, তবে আপনি সর্বদা একটি মিস করতে পারেন।
- আনুষ্ঠানিক যাচাই । আরও কঠিন, তবে সঠিকভাবে গাণিতিক প্রমাণ তৈরি করে, মূলত ডকুমেন্টেশন এবং পরীক্ষাগুলি "মানব" / মেশিন যাচাইযোগ্য পদ্ধতিতে একীকরণ করে! অবশ্যই আপনার আনুষ্ঠানিক বিবরণে কোনও বাগ নেই ;-)
উবুন্টু 18.10, জিসিসি 8.2.0 এ পরীক্ষিত।