ঠিক কীভাবে___গ্রাহক __ ((কনস্ট্রাক্টর)) কাজ করে?


347

এটি বেশ পরিষ্কার মনে হয়েছে যে এটি জিনিসগুলি সেট আপ করার কথা।

  1. কখন এটি চালায়?
  2. কেন দুটি বন্ধনী আছে?
  3. কি __attribute__একটি ফাংশন? একটি ম্যাক্রো? বাক্য গঠন?
  4. এটি সি তে কাজ করে? সি ++?
  5. এটি যে ফাংশনটির সাথে কাজ করে তা স্থিতিশীল হওয়া দরকার?
  6. কখন __attribute__((destructor))চালায়?

উদ্দেশ্য-সি উদাহরণ :

__attribute__((constructor))
static void initialize_navigationBarImages() {
  navigationBarImages = [[NSMutableDictionary alloc] init];
}

__attribute__((destructor))
static void destroy_navigationBarImages() {
  [navigationBarImages release];
}

উত্তর:


273
  1. এটি যখন ভাগ করা লাইব্রেরিটি লোড হয় তখন সাধারণত চালানো হয় প্রোগ্রামের শুরু করার সময়।
  2. সমস্ত জিসিসির বৈশিষ্ট্যগুলি এমনই হয়; সম্ভবত তাদের ফাংশন কল থেকে পৃথক।
  3. জিসিসি-নির্দিষ্ট সিনট্যাক্স।
  4. হ্যাঁ, এটি সি এবং সি ++ এ কাজ করে।
  5. না, ফাংশনটি স্থির হওয়ার দরকার নেই।
  6. ভাগ করা লাইব্রেরিটি লোড করা হয়, সাধারণত প্রোগ্রাম প্রস্থানের সময় চালকগুলি চালায়।

সুতরাং, কনস্ট্রাক্টর এবং ডেস্ট্রাক্টররা যেভাবে কাজ করেন তা হ'ল শেয়ার্ড অবজেক্ট ফাইলটিতে বিশেষ বিভাগ (.ctors এবং .dters ELF) থাকে যা যথাক্রমে কনস্ট্রাক্টর এবং ডেস্ট্রাক্টর বৈশিষ্ট্যযুক্ত চিহ্নিত ফাংশনগুলির রেফারেন্স ধারণ করে। লাইব্রেরিটি যখন ডায়নামিক লোডার প্রোগ্রামটি লোড / আনলোড করা হয় (এলডি.সো বা সামসুচ) তখন এই বিভাগগুলি বিদ্যমান কিনা তা পরীক্ষা করে থাকে এবং যদি তা হয় তবে এতে উল্লিখিত ফাংশনগুলি কল করে।

এটি ভাবতে আসুন, সম্ভবত সাধারণ স্ট্যাটিক লিঙ্কারে কিছু অনুরূপ ম্যাজিক রয়েছে যাতে ব্যবহারকারী স্ট্যাটিক বা গতিশীল লিঙ্কিং বেছে নিলে নির্বিশেষে একই কোডটি স্টার্টআপ / শাটডাউনে চালিত হয়।


49
ডাবল বন্ধনী তাদের "ম্যাক্রো আউট" ( #define __attribute__(x)) সহজ করে তোলে । আপনার যদি একাধিক বৈশিষ্ট্য থাকে, যেমন, __attribute__((noreturn, weak))যদি বন্ধনীর এক সেট থাকে তবে "ম্যাক্রো আউট" করা শক্ত হবে।
ক্রিস জেস্টার-ইয়াং

7
এটি দিয়ে করা হয় না .init/.fini। (আপনি বৈধভাবে একক অনুবাদ ইউনিটে একাধিক কনস্ট্রাক্টর এবং ডেস্ট্রাক্টর থাকতে পারেন, একা লাইব্রেরিতে একাধিক কিছুই মনে রাখবেন না - কীভাবে এটি কাজ করবে?) পরিবর্তে, ইএলএফ বাইনারি ফর্ম্যাট (লিনাক্স ইত্যাদি) ব্যবহার করে প্ল্যাটফর্মগুলিতে কনস্ট্রাক্টর এবং ডেস্ট্রাক্টরগুলি উল্লেখ করা হয়েছে মধ্যে .ctorsএবং .dtorsহেডার বিভাগে। এটা ঠিক যে, পুরানো দিনের মধ্যে ফাংশন নামে initএবং finiগতিশীল লাইব্রেরি লোড এবং আন যদি তারা অস্তিত্ব চালানো হবে, কিন্তু যে এখন অবচিত এর এটা উত্তম প্রক্রিয়া দ্বারা প্রতিস্থাপিত।
ephemient

7
@ জেসায়জাক না, কারণ ভেরিয়্যাডিক ম্যাক্রোস একটি সিসি এক্সটেনশন এবং ম্যাক্রো আউট করার মূল কারণ __attribute__আপনি যদি সিসি ব্যবহার করছেন না, যেহেতু এটিও একটি সিসি এক্সটেনশন।
ক্রিস জেস্টার-ইয়াং

9
@ ক্রিসজেস্টার-ইয়ং বৈচিত্র্যযুক্ত ম্যাক্রোগুলি একটি স্ট্যান্ডার্ড সি 99 বৈশিষ্ট্য, কোনও জিএনইউ এক্সটেনশন নয়।
jcayzac

4
"আপনার বর্তমান কালের ব্যবহার (" তৈরি "এর পরিবর্তে" মেক করুন "- ডাবল পেরেনগুলি এখনও তাদেরকে ম্যাক্রো আউট করা সহজ করে দেয় You আপনি ভুল পেডেন্টিক ট্রিটি ছড়িয়ে দিয়েছেন
জিম বাল্টার

64

.init/ .finiঅবচয়হীন নয়। এটি এখনও ইএলএফ স্ট্যান্ডার্ডের একটি অংশ এবং আমি সাহস করে বলতে পারি যে এটি চিরকাল থাকবে। কোড লোড / আনলোড করা অবস্থায় কোড ইন .init/ .finiলোডার / রানটাইম-লিঙ্কার দ্বারা চালিত হয়। অর্থাৎ প্রতিটি ইএলএফ লোডের উপর (উদাহরণস্বরূপ একটি ভাগ করা লাইব্রেরি) কোড .initচালানো হবে। এখনও একই জিনিসটি অর্জন করতে সেই প্রক্রিয়াটি ব্যবহার করা সম্ভব __attribute__((constructor))/((destructor))। এটি পুরাতন স্কুল তবে এর কিছু সুবিধা রয়েছে।

.ctors/ .dtorsপ্রক্রিয়া উদাহরণস্বরূপ সিস্টেম-rtl / লোডার / লিঙ্কার-স্ক্রিপ্ট দ্বারা সমর্থন প্রয়োজন। এটি সমস্ত সিস্টেমে উপলভ্য হওয়া অনেক দূরে, উদাহরণস্বরূপ গভীরভাবে এম্বেড হওয়া সিস্টেমগুলি যেখানে কোডটি বেয়ার ধাতব উপর কার্যকর করে। __attribute__((constructor))/((destructor))যেমন জিসিসি সমর্থিত হলেও এটি নিশ্চিত নয় যে এটি পরিচালনা করবে লিঙ্কার এবং এটি চালানোর জন্য লোডার (বা কিছু ক্ষেত্রে, বুট-কোড) এর উপর নির্ভর করে। ব্যবহার .init/ .finiপরিবর্তে, সবচেয়ে সহজ উপায় হ'ল লিঙ্কার পতাকা ব্যবহার করা: -আইনিট & -ফিনি (যেমন জিসিসি কমান্ড লাইন থেকে, বাক্য গঠনটি হবে -Wl -init my_init -fini my_fini)।

উভয় পদ্ধতি সমর্থনকারী সিস্টেমে, একটি সম্ভাব্য সুবিধা হ'ল কোডটি .initআগে চালানো হয় .ctorsএবং .finiপরে কোড করা হয় .dtors। যদি অর্ডার প্রাসঙ্গিক হয় তবে কমপক্ষে একটি অপরিশোধিত তবে init / প্রস্থান ফাংশনগুলির মধ্যে পার্থক্য করার সহজ উপায়।

একটি বড় অসুবিধা হ'ল আপনি সহজেই প্রতিটি লোডযোগ্য মডিউল প্রতি এক _initএবং একাধিক _finiফাংশন রাখতে পারবেন না এবং সম্ভবত .soউদ্দেশ্যপ্রণোদিতের চেয়ে বেশি অংশে কোড টুকরো করতে হবে । অন্যটি হ'ল উপরে বর্ণিত লিঙ্কার পদ্ধতিটি ব্যবহার করার সময়, একটি আসল _ ইনট এবং _finiডিফল্ট ফাংশন (সরবরাহিত crti.o) প্রতিস্থাপন করে । এখানেই সব ধরণের সূচনা সাধারণত ঘটে থাকে (লিনাক্স এ এটি যেখানে গ্লোবাল ভেরিয়েবল অ্যাসাইনমেন্ট শুরু করা হয়)। প্রায় একটি উপায় এখানে বর্ণিত হয়

উপরের লিঙ্কে লক্ষ্য করুন যে আসলটিতে _init()এখনও ক্যাসকেডিংয়ের প্রয়োজন নেই কারণ এটি এখনও রয়েছে। দ্যcallইনলাইন সমাবেশ তবে এ এক্স 86-স্মৃতিসম্বন্ধীয় এবং একটি ফাংশন সমাবেশ (উদাহরণস্বরূপ এআরএম মত) অনেক অন্যান্য আর্কিটেকচারের জন্য সম্পূর্ণ ভিন্ন দেখাবে থেকে কল করা হয়। অর্থাৎ কোড স্বচ্ছ নয়।

.init/ .finiএবং .ctors/ .detorsপ্রক্রিয়া সমান, তবে বেশ নয়। মধ্যে Code .init/ .finiরানে "যেমন আছে"। অর্থাৎ আপনার .init/ এ বেশ কয়েকটি কার্যকারিতা থাকতে পারে .fini, তবে অনেক ছোট .soফাইলগুলিতে কোড না ভেঙে এফআইকে সিনট্যাকটিক্যালি এগুলি সম্পূর্ণরূপে স্বচ্ছ সিতে রেখে দেওয়া কঠিন ।

.ctors/ .dtorsভিন্নভাবে চেয়ে সংগঠিত .init/ .fini.ctors/ .dtorsবিভাগগুলি উভয়ই ফাংশনগুলিতে পয়েন্টার সহ কেবল সারণী এবং "কলার" একটি সিস্টেম-সরবরাহিত লুপ যা প্রতিটি ফাংশনকে পরোক্ষভাবে ডাকে। লুপ-কলারটি আর্কিটেকচার নির্দিষ্ট হতে পারে তবে এটি সিস্টেমের অংশ হিসাবে (এটি যদি বাস্তবে বিদ্যমান থাকে তবে) তাতে কিছু আসে যায় না।

নিম্নলিখিত স্নিপেট .ctorsফাংশন অ্যারেতে নতুন ফাংশন পয়েন্টার যুক্ত করে , মূলত একইভাবে __attribute__((constructor))(পদ্ধতি সহ সহাবস্থান করতে পারে) __attribute__((constructor)))

#define SECTION( S ) __attribute__ ((section ( S )))
void test(void) {
   printf("Hello\n");
}
void (*funcptr)(void) SECTION(".ctors") =test;
void (*funcptr2)(void) SECTION(".ctors") =test;
void (*funcptr3)(void) SECTION(".dtors") =test;

একটি সম্পূর্ণ ভিন্ন স্ব-উদ্ভাবিত বিভাগে ফাংশন পয়েন্টার যুক্ত করতে পারে। পরিবর্তিত লিঙ্কার স্ক্রিপ্ট এবং এ জাতীয় ক্ষেত্রে লোডার .ctors/ .dtorsলুপের নকল করা একটি অতিরিক্ত ফাংশন প্রয়োজন। তবে এটির মাধ্যমে এক্সিকিউশন অর্ডারের উপর আরও ভাল নিয়ন্ত্রণ অর্জন করা যায়, ইন-আর্গুমেন্ট এবং রিটার্ন কোড হ্যান্ডলিং এটা (উদাহরণস্বরূপ, সি ++ প্রকল্পে, বৈশ্বিক নির্মাণকারীদের আগে বা পরে কিছু চালানোর প্রয়োজনে এটি কার্যকর হবে)।

আমি __attribute__((constructor))/((destructor))যেখানে সম্ভব তা পছন্দ করি , এটি একটি সহজ এবং মার্জিত সমাধান এমনকি এটি প্রতারণার মতো বলে মনে হয়। আমার মতো খালি ধাতব কোডারদের জন্য, এটি সর্বদা একটি বিকল্প নয়।

লিঙ্কারস এবং লোডার বইয়ের কিছু ভাল রেফারেন্স ।


কিভাবে লোডার এই ফাংশন কল করতে পারেন? এই ফাংশনগুলি প্রক্রিয়া ঠিকানা স্পেসে গ্লোবাল এবং অন্যান্য ফাংশন ব্যবহার করতে পারে, তবে লোডার তার নিজস্ব ঠিকানা স্থান সহ একটি প্রক্রিয়া, তাই না?
ব্যবহারকারী 2162550

@ user2162550 না, ld-linux.so.2 (সাধারণ "ইন্টারপ্রিটার", ডায়নামিক লাইব্রেরিগুলির জন্য লোডার যা সমস্ত গতিযুক্ত সংযুক্ত এক্সিকিউটেবলের উপর সঞ্চালিত হয়) এক্সিকিউটেবলের নিজেই খুব ঠিকানার জায়গায় চলে runs সাধারণভাবে ডায়নামিক লাইব্রেরি লোডার নিজেই ব্যবহারকারী স্পেসের সাথে নির্দিষ্ট কিছু, থ্রেডের প্রসঙ্গে যা একটি লাইব্রেরি সংস্থান অ্যাক্সেস করার চেষ্টা করে running
পল স্টেলিয়ান

যখন আমি কোড থেকে এক্সিকিউ () ডাস্ট্রেক্টর সহ __attribute__((constructor))/((destructor))চালিত করি না। উপরোক্ত হিসাবে .dtor এ এন্ট্রি যুক্ত করার মতো কয়েকটি বিষয় চেষ্টা করেছি tried তবে কোনও সাফল্য নেই। সমস্যাটি নুমাক্টল দিয়ে কোডটি চালিয়ে নকল করা সহজ। উদাহরণস্বরূপ, ধরে নিন টেস্ট_কোডে ডেস্ট্রাক্টর রয়েছে (সমস্যাটি ডিবাগ করার জন্য কন্সট্রাক্টরের একটি প্রিন্টফ এবং ডেস্ট্রাক্টর ফাংশন যুক্ত করুন)। তারপরে দৌড়াও LD_PRELOAD=./test_code numactl -N 0 sleep 1। আপনি দেখতে পাবেন যে কনস্ট্রাক্টরকে দু'বার বলা হয়েছে তবে ডাস্ট্রাস্টর কেবল একবার।
বি আবালি

39

এই পৃষ্ঠাটি constructorএবং destructorবৈশিষ্ট্য প্রয়োগ এবং ELF এর মধ্যে যে বিভাগগুলি তাদের কাজ করার অনুমতি দেয় সে সম্পর্কে দুর্দান্ত ধারণা প্রদান করে । এখানে প্রদত্ত তথ্য হজম করার পরে, আমি কিছুটা অতিরিক্ত তথ্য সংকলন করেছি এবং (উপরের মাইকেল অ্যামব্রাসের বিভাগের উদাহরণ ধার করে) ধারণাগুলি বর্ণনা করার জন্য এবং আমার শিখতে সহায়তা করার জন্য একটি উদাহরণ তৈরি করেছি। এই ফলাফলগুলি উদাহরণ উত্স সহ নীচে সরবরাহ করা হয়েছে।

এই থ্রেডে বর্ণিত হিসাবে, constructorএবং destructorবৈশিষ্ট্যগুলি বস্তু ফাইলের .ctorsএবং .dtorsবিভাগে এন্ট্রি তৈরি করে । আপনি তিনটি উপায়ে যে কোনও একটিতে ফাংশনের জন্য রেফারেন্স রাখতে পারেন place (1) হয় sectionগুণাবলী ব্যবহার করে ; (2) constructorএবং destructorবৈশিষ্ট্য বা (3) একটি ইনলাইন-এসেম্বল কল সহ (অ্যামব্রসের উত্তরে লিঙ্কটি উল্লেখ করা হয়েছে)।

বৈশিষ্ট্যগুলির ব্যবহার constructorএবং destructorবৈশিষ্ট্যগুলি আপনাকে কন্সট্রাক্টর / ডেস্ট্রাক্টরকে তার সম্পাদনের আদেশটি কল করার আগে main()বা ফিরে আসার আগে তার নিয়ন্ত্রণের জন্য অতিরিক্তভাবে একটি অগ্রাধিকার বরাদ্দ করতে দেয় । প্রদত্ত অগ্রাধিকারের মান যত কম হবে, কার্যকর করার অগ্রাধিকারটি তত বেশি হবে (প্রধান () এর আগে উচ্চ অগ্রাধিকারের পূর্বে নিম্ন অগ্রাধিকারগুলি কার্যকর হবে - এবং পরে মূল ()) পরে উচ্চতর অগ্রাধিকার প্রাপ্ত হবে। অগ্রাধিকার মান দিতে থেকে বড় হওয়া উচিত100 বাস্তবায়নের 0-100 মধ্যে কম্পাইলার মজুদ অগ্রাধিকার মান হিসাবে। এ constructorবা destructorঅগ্রাধিকার সহ সুনির্দিষ্ট একটি এর আগে কার্যকর হয় constructorবা destructorঅগ্রাধিকার ছাড়াই নির্দিষ্ট করা হয়।

'বিভাগ' বৈশিষ্ট্য বা ইনলাইন- অ্যাসেমব্লির সাহায্যে আপনি .initএবং .finiELF কোড বিভাগে ক্রিয়াকলাপের রেফারেন্স রাখতে পারেন যা কোনও নির্মাতার আগে এবং কোনও ডেস্ট্রাক্টরের পরে যথাক্রমে কার্যকর হবে। .initবিভাগে রাখা ফাংশন রেফারেন্স দ্বারা ডাকা যে কোনও ফাংশন, ফাংশন রেফারেন্সের আগেই (যথারীতি) কার্যকর করা হবে।

আমি নীচের উদাহরণে তাদের প্রত্যেককে চিত্রিত করার চেষ্টা করেছি:

#include <stdio.h>
#include <stdlib.h>

/*  test function utilizing attribute 'section' ".ctors"/".dtors"
    to create constuctors/destructors without assigned priority.
    (provided by Michael Ambrus in earlier answer)
*/

#define SECTION( S ) __attribute__ ((section ( S )))

void test (void) {
printf("\n\ttest() utilizing -- (.section .ctors/.dtors) w/o priority\n");
}

void (*funcptr1)(void) SECTION(".ctors") =test;
void (*funcptr2)(void) SECTION(".ctors") =test;
void (*funcptr3)(void) SECTION(".dtors") =test;

/*  functions constructX, destructX use attributes 'constructor' and
    'destructor' to create prioritized entries in the .ctors, .dtors
    ELF sections, respectively.

    NOTE: priorities 0-100 are reserved
*/
void construct1 () __attribute__ ((constructor (101)));
void construct2 () __attribute__ ((constructor (102)));
void destruct1 () __attribute__ ((destructor (101)));
void destruct2 () __attribute__ ((destructor (102)));

/*  init_some_function() - called by elf_init()
*/
int init_some_function () {
    printf ("\n  init_some_function() called by elf_init()\n");
    return 1;
}

/*  elf_init uses inline-assembly to place itself in the ELF .init section.
*/
int elf_init (void)
{
    __asm__ (".section .init \n call elf_init \n .section .text\n");

    if(!init_some_function ())
    {
        exit (1);
    }

    printf ("\n    elf_init() -- (.section .init)\n");

    return 1;
}

/*
    function definitions for constructX and destructX
*/
void construct1 () {
    printf ("\n      construct1() constructor -- (.section .ctors) priority 101\n");
}

void construct2 () {
    printf ("\n      construct2() constructor -- (.section .ctors) priority 102\n");
}

void destruct1 () {
    printf ("\n      destruct1() destructor -- (.section .dtors) priority 101\n\n");
}

void destruct2 () {
    printf ("\n      destruct2() destructor -- (.section .dtors) priority 102\n");
}

/* main makes no function call to any of the functions declared above
*/
int
main (int argc, char *argv[]) {

    printf ("\n\t  [ main body of program ]\n");

    return 0;
}

আউটপুট:

init_some_function() called by elf_init()

    elf_init() -- (.section .init)

    construct1() constructor -- (.section .ctors) priority 101

    construct2() constructor -- (.section .ctors) priority 102

        test() utilizing -- (.section .ctors/.dtors) w/o priority

        test() utilizing -- (.section .ctors/.dtors) w/o priority

        [ main body of program ]

        test() utilizing -- (.section .ctors/.dtors) w/o priority

    destruct2() destructor -- (.section .dtors) priority 102

    destruct1() destructor -- (.section .dtors) priority 101

উদাহরণটি কনস্ট্রাক্টর / ডেস্ট্রাক্টর আচরণ সিমেন্টে সহায়তা করেছিল, আশা করি এটি অন্যদের জন্যও কার্যকর হবে।


আপনি কোথায় পেয়েছেন যে "আপনার দেওয়া অগ্রাধিকার মানগুলি অবশ্যই 100 এর চেয়ে বেশি হওয়া উচিত"? তথ্যটি জিসিসি ফাংশন বিশিষ্ট ডকুমেন্টেশনে উপস্থিত নেই।
জাস্টিন

4
আইআইআরসি, এখানে বেশ কয়েকটি রেফারেন্স ছিল, প্যাচচ: কনস্ট্রাক্টর / ডেস্ট্রাক্টর আর্গুমেন্টগুলির জন্য সমর্থন অগ্রাধিকার যুক্তি ( MAX_RESERVED_INIT_PRIORITY) এবং সেগুলি সি ++ ( init_priority) 7.7 সি ++ -র মতো নির্দিষ্ট - পরিবর্তনশীল, ফাংশন এবং টাইপ বৈশিষ্ট্যগুলির মতো । তারপর আমি এটা দিয়ে চেষ্টা 99: warning: constructor priorities from 0 to 100 are reserved for the implementation [enabled by default] void construct0 () __attribute__ ((constructor (99)));
ডেভিড সি র্যাঙ্কিন

1
আহ। আমি ক্ল্যাং সহ অগ্রাধিকার <100 চেষ্টা করেছিলাম এবং এটি মনে হচ্ছে এটি কাজ করছে, তবে আমার সাধারণ পরীক্ষার কেস (একক সংকলন ইউনিট) খুব সহজ
জাস্টিন

1
স্ট্যাটিক গ্লোবাল ভেরিয়েবল (স্ট্যাটিক সিটার) এর অগ্রাধিকার কী?
ছদ্মবেশী

2
স্ট্যাটিক গ্লোবালের প্রভাব এবং দৃশ্যমানতা নির্ভর করবে আপনার প্রোগ্রামটি কীভাবে কাঠামোগত করা হয়েছে (যেমন একক ফাইল, একাধিক ফাইল ( অনুবাদ ইউনিট )) এবং বিশ্বব্যাপী ঘোষিত হয় দেখুন: স্ট্যাটিক (কীওয়ার্ড) , বিশেষত স্ট্যাটিক গ্লোবাল ভেরিয়েবলের বিবরণ।
ডেভিড সি র্যাঙ্কিন

7

কীভাবে, কেন এবং কখন এই সহজে ব্যবহারযোগ্য, তবুও কৃপণভাবে নির্মাণের একটি "কংক্রিট" (এবং সম্ভবত দরকারী ) উদাহরণ এখানে ...

Xcode যা সিদ্ধান্ত নিতে একটি "বিশ্বব্যাপী" "ব্যবহারকারীর ডিফল্ট" ব্যবহার XCTestObserverবর্গ spews এটা হৃদয় থেকে নিজেকে অবরুদ্ধ কনসোল।

এই উদাহরণে ... আমি যখন এই স্পিডো-লাইব্রেরিটি স্পষ্টভাবে লোড করি, আসুন এটির কল করুন ... libdemure.a, আমার পরীক্ষার লক্ষ্য á লা ..

OTHER_LDFLAGS = -ldemure

আমি চাই..

  1. লোড এ (অর্থাত্‍ যখন XCTestআমার পরীক্ষার বান্ডিলটি লোড হয়), "ডিফল্ট" XCTest"পর্যবেক্ষক" শ্রেণিকে ওভাররাইড করুন ... ( constructorফাংশনটির মাধ্যমে ) পিএস: আমি যতদূর বলতে পারি .. এখানে যা কিছু করা যায় তা আমার ভিতরে সমমানের প্রভাব দিয়ে করা যেতে পারে শ্রেণি ' + (void) load { ... }পদ্ধতি।

  2. আমার পরীক্ষা চালান .... এই ক্ষেত্রে, লগগুলিতে কম বুদ্ধিমানের (অনুরোধের ভিত্তিতে বাস্তবায়ন)

  3. "গ্লোবাল" XCTestObserverশ্রেণিটিকে তার প্রাথমিক অবস্থায় ফিরিয়ে দিন .. যাতে XCTestব্যান্ডউইগেনের (অন্যান্য। লিঙ্কযুক্ত libdemure.a) অন্য রানের রেকর্ড না ঘটে । আমি অনুমান করি historতিহাসিকভাবে এটি সম্পন্ন হয়েছিল dealloc.. তবে আমি সেই পুরানো হ্যাগের সাথে ঝামেলা শুরু করতে যাচ্ছি না start

তাই ...

#define USER_DEFS NSUserDefaults.standardUserDefaults

@interface      DemureTestObserver : XCTestObserver @end
@implementation DemureTestObserver

__attribute__((constructor)) static void hijack_observer() {

/*! here I totally hijack the default logging, but you CAN
    use multiple observers, just CSV them, 
    i.e. "@"DemureTestObserverm,XCTestLog"
*/
  [USER_DEFS setObject:@"DemureTestObserver" 
                forKey:@"XCTestObserverClass"];
  [USER_DEFS synchronize];
}

__attribute__((destructor)) static void reset_observer()  {

  // Clean up, and it's as if we had never been here.
  [USER_DEFS setObject:@"XCTestLog" 
                forKey:@"XCTestObserverClass"];
  [USER_DEFS synchronize];
}

...
@end

লিঙ্কার পতাকা ব্যতীত ... (ফ্যাশন-পুলিশ ঝাঁকুনি কাপার্তিনো প্রতিশোধের দাবিতে , তবুও অ্যাপলের ডিফল্ট এখানে যেমন পছন্দসই রয়েছে, তেমনটি রয়েছে )

এখানে চিত্র বর্ণনা লিখুন

সঙ্গে -ldemure.alinker পতাকা ... (বোধগম্য ফলাফল, খাবি ... "ধন্যবাদ constructor/ destructor" ... ভিড় চিয়ার্স ) এখানে চিত্র বর্ণনা লিখুন


1

এখানে আরও কংক্রিটের উদাহরণ রয়েছে t এটি একটি ভাগ করা লাইব্রেরির জন্য। ভাগ করা লাইব্রেরির মূল কাজটি হ'ল স্মার্ট কার্ড পাঠকের সাথে যোগাযোগ করা। তবে এটি রানটাইম ওভার ইউডিপি-তে 'কনফিগারেশন তথ্য'ও পেতে পারে। Udp একটি থ্রেড দ্বারা পরিচালিত হয় যা ডিআর সময়ে শুরু করা আবশ্যক

__attribute__((constructor))  static void startUdpReceiveThread (void) {
    pthread_create( &tid_udpthread, NULL, __feigh_udp_receive_loop, NULL );
    return;

  }

গ্রন্থাগারটি গ।


1
লাইব্রেরিটি সি ++ তে লেখা থাকলে একটি অদ্ভুত পছন্দ, যেহেতু সাধারণ গ্লোবাল ভেরিয়েবল কনস্ট্রাক্টর হ'ল সি ++ এ প্রি-মাইনের কোড চালানোর আইডিম্যাটিক পদ্ধতি।
নিকোলাস উইলসন

@ নিকোলাস উইলসন গ্রন্থাগারটি আসলে সি-তে লেখা হয়েছিল। আপনি কীভাবে সি এর পরিবর্তে সি ++ টাইপ করবেন তা জানেন না।
ড্রিওলি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.