আমি কীভাবে পোর্টেবলভাবে একটি সি ++ ফাংশন কল করতে পারি যা কিছু প্ল্যাটফর্মে একটি চর ** এবং অন্যদের কাছে কনস্টের চর ** নেয়?


91

আমার লিনাক্স (এবং ওএস এক্স) মেশিনে, iconv()ফাংশনটির এই প্রোটোটাইপ রয়েছে:

size_t iconv (iconv_t, char **inbuf...

ফ্রিবিএসডি থাকাকালীন এটিকে দেখতে দেখতে এমন দেখাচ্ছে:

size_t iconv (iconv_t, const char **inbuf...

আমি উভয় প্ল্যাটফর্মে আমার সি ++ কোড তৈরি করতে চাই। সি সংকলকগুলির সাথে, char**একটি const char**প্যারামিটারের জন্য একটি পাস (বা বিপরীতে) সাধারণত একটি নিছক সতর্কতা প্রকাশ করে; তবে সি ++ এ এটি মারাত্মক ত্রুটি। সুতরাং আমি যদি পাস করি তবে char**এটি বিএসডি-তে সংকলন করবে না এবং আমি যদি পাস করি তবে const char**এটি লিনাক্স / ওএস এক্স-এ সংকলিত হবে না the প্ল্যাটফর্মটি সনাক্ত করার চেষ্টা না করে আমি কীভাবে উভয়কে সংকলিত কোড লিখতে পারি?

আমার একটি (ব্যর্থ) ধারণা ছিল একটি স্থানীয় প্রোটোটাইপ সরবরাহ করা যা শিরোলেখ দ্বারা প্রদত্ত যে কোনওটিকে ওভাররাইড করে:

void myfunc(void) {
    size_t iconv (iconv_t, char **inbuf);
    iconv(foo, ptr);
}

এটি ব্যর্থ হয়েছে কারণ iconvসি লিঙ্কেজ প্রয়োজন, এবং আপনি extern "C"কোনও ফাংশনের মধ্যে রাখতে পারবেন না (কেন নয়?)

আমি যে সর্বোত্তম কার্যকরী ধারণা নিয়ে এসেছি তা হ'ল ফাংশন পয়েন্টারটি নিজেই কাস্ট করা:

typedef void (*func_t)(iconv_t, const char **);
((func_t)(iconv))(foo, ptr);

তবে এটিতে আরও গুরুতর ত্রুটিগুলি মাস্ক করার সম্ভাবনা রয়েছে।


31
আপনার প্রথম প্রশ্নটির জন্য তাই :)
অলমো

24
ফ্রিবিএসডি-তে একটি বাগ লগ করুন। এর পসিক্স বাস্তবায়নের জন্য অবিচ্ছিন্ন হওয়া iconvদরকার inbuf
ড্রিমলাক্স

4
এর মতো ফাংশনটি ingালাই অ-বহনযোগ্য is
জোনাথন গ্রিনস্পান 20

4
@ ড্রিমলাক্স: বাগ রিপোর্ট জমা দেওয়ার কোনও প্রভাব পড়ার সম্ভাবনা নেই; FreeBSD 'র বর্তমান সংস্করণের দৃশ্যত ইতিমধ্যে iconvছাড়া const: svnweb.freebsd.org/base/stable/9/include/...
ফ্রেড ফু

4
@ এলারসম্যানস: এটি জেনে রাখা ভাল! আমি কখনই ফ্রিবিএসডি ব্যবহার করি নি তবে সর্বশেষতম সংস্করণটি সর্বশেষ মানটিকে সমর্থন করে know
ড্রিমলাক্স

উত্তর:


57

আপনি যা চান তা যদি কেবল কিছু স্থির বিষয়গুলিতে অন্ধ দৃষ্টি দেওয়া হয়, তবে আপনি এমন রূপান্তর ব্যবহার করতে পারেন যা পার্থক্যটিকে ঝাপসা করে, অর্থাত্ ** চর এবং ** চরকে ** আন্তঃযোগযোগ্য করে তুলবে:

template<class T>
class sloppy {}; 

// convert between T** and const T** 
template<class T>
class sloppy<T**>
{
    T** t;
    public: 
    sloppy(T** mt) : t(mt) {}
    sloppy(const T** mt) : t(const_cast<T**>(mt)) {}

    operator T** () const { return t; }
    operator const T** () const { return const_cast<const T**>(t); }
};

তারপরে প্রোগ্রামে:

iconv(c, sloppy<char**>(&in) ,&inlen, &out,&outlen);

opড়ু () একটি char**বা একটি নেয় const char*এবং আইকনভের দ্বিতীয় প্যারামিটারের দাবি অনুসারে এটিকে একটি char**বা এ রূপান্তর করে const char*

আপডেট: কনস্ট_কাস্ট এবং কল স্লোপি কাস্ট হিসাবে নয় ব্যবহার করতে পরিবর্তিত হয়েছে।


এটি বেশ ভালভাবে কাজ করে এবং সি ++ 11 এর প্রয়োজনীয়তা ছাড়াই নিরাপদ এবং সোজা বলে মনে হচ্ছে। আমি এর সাথে যাচ্ছি! ধন্যবাদ!
ridiculous_fish

4
আমি আমার উত্তর বলেন, আমি এই সি ++ 03 কঠোর এলিয়াসিং লঙ্ঘন মনে করি, যাতে অর্থে এটা করে সি ++ 11 প্রয়োজন। আমি যদিও ভুল হতে পারি, কেউ যদি এটিকে রক্ষা করতে চায়।
স্টিভ জেসোপ

4
দয়া করে সি ++ এ সি-স্টাইলের কাস্টগুলিকে উত্সাহিত করবেন না; আমি ভুল না হলে আপনি sloppy<char**>()সরাসরি সেখানে প্রাথমিক কল করতে পারেন call
মিশা গার্নি

এটি অবশ্যই সি-স্টাইলের কাস্টের মতো একই অপারেশন, তবে বিকল্প সি ++ সিনট্যাক্স ব্যবহার করছে। আমার ধারণা এটি অন্য পরিস্থিতিতে সি-স্টাইলের ক্যাসেটগুলি ব্যবহার করে পাঠকদের নিরুৎসাহিত করতে পারে। উদাহরণস্বরূপ, C ++ সিনট্যাক্স কাস্টের জন্য কাজ করবে না (char**)&inযদি আপনি প্রথমে টাইপডেফ না করেন char**
স্টিভ জেসপ

ভাল হ্যাক। সম্পূর্ণতার জন্য, আপনি সম্ভবত এটি তৈরি করতে পারেন (ক) সর্বদা একটি কনস্ট চর * কনস্ট * গ্রহণ করে, ভেরিয়েবলটি পরিবর্তন করা হবে না বলে ধরে নেওয়া বা (খ) কোনও দুটি ধরণের দ্বারা প্যারামিটারাইজিং করা এবং এটি তাদের মধ্যে আবদ্ধ করে দেওয়া।
জ্যাক ভি।

33

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

#include <iostream>
#include <stddef.h>
#include <type_traits>

// I've declared this just so the example is portable:
struct iconv_t { };

// use_const<decltype(&iconv)>::value will be 'true' if the function is
// declared as taking a char const**, otherwise ::value will be false.
template <typename>
struct use_const;

template <>
struct use_const<size_t(*)(iconv_t, char**, size_t*, char**, size_t*)>
{
    enum { value = false };
};

template <>
struct use_const<size_t(*)(iconv_t, char const**, size_t*, char**, size_t*)>
{
    enum { value = true };
};

এখানে একটি উদাহরণ যা আচরণটি দেখায়:

size_t iconv(iconv_t, char**, size_t*, char**, size_t*);
size_t iconv_const(iconv_t, char const**, size_t*, char**, size_t*);

int main()
{
    using std::cout;
    using std::endl;

    cout << "iconv: "       << use_const<decltype(&iconv)      >::value << endl;
    cout << "iconv_const: " << use_const<decltype(&iconv_const)>::value << endl;
}

একবার আপনি প্যারামিটার প্রকার যোগ্যতা সনাক্ত করা সম্ভব, আপনি দুই মোড়কের ফাংশন যে কল লিখতে পারেন iconv: এক যে কল iconvএকটি সঙ্গে char const**এবং যুক্তি এক যে কল iconvএকটি সঙ্গে char**যুক্তি।

ফাংশন টেম্পলেট বিশেষায়িতকরণ এড়ানো উচিত, আমরা বিশেষায়নের জন্য একটি শ্রেণির টেম্পলেট ব্যবহার করি। মনে রাখবেন যে আমরা যে সমস্ত বিশেষায়িত ব্যবহার করি তা তাত্ক্ষণিকভাবে হয় তা নিশ্চিত করার জন্য আমরা প্রতিটি চালককে একটি ফাংশন টেম্পলেটও করি। যদি সংকলকটি ভুল বিশেষত্বের জন্য কোড উত্পন্ন করার চেষ্টা করে তবে আপনি ত্রুটি পাবেন।

এরপরে call_iconvএটিকে iconvসরাসরি কল করার মতো সহজ কল করার জন্য আমরা এর ব্যবহারটি গুটিয়ে রাখি । নিম্নলিখিতটি কীভাবে এটি লেখা যেতে পারে তা দেখিয়ে একটি সাধারণ প্যাটার্ন দেওয়া হল:

template <bool UseConst>
struct iconv_invoker
{
    template <typename T>
    static size_t invoke(T const&, /* arguments */) { /* etc. */ }
};

template <>
struct iconv_invoker<true>
{
    template <typename T>
    static size_t invoke(T const&, /* arguments */) { /* etc. */ }
};

size_t call_iconv(/* arguments */)
{
    return iconv_invoker<
        use_const<decltype(&iconv)>::value
    >::invoke(&iconv, /* arguments */);
}

(এই পরবর্তী যুক্তিটি পরিষ্কার করে সাধারণীকরণ করা যেতে পারে; আমি এর প্রতিটি টুকরোটি পরিষ্কারভাবে তৈরি করার চেষ্টা করেছি আশা করি এটি কীভাবে কাজ করে তা আরও পরিষ্কার করে দেওয়া।)


4
সেখানে দুর্দান্ত যাদু। :) আমি উজ্জীবিত হয়েছি কারণ দেখে মনে হচ্ছে এটি প্রশ্নের উত্তর দিয়েছে, তবে আমি এটি যাচাই করেছিলাম তা যাচাই করেছিলাম না, এবং এটি দেখার জন্য আমি যথেষ্ট পরিমাণে সি সি ++ জানি না যে এটি ঠিক আছে কিনা। :)
অলমো

7
একটি নোট হিসাবে: decltypeC ++ 11 প্রয়োজন।
মিশা গার্নি

4
+1 লোল ... সুতরাং আপনার #ifdefকোডটি 30 টি বিজোড় লাইনের সাথে শেষ হওয়া প্ল্যাটফর্মটির জন্য একটি পরীক্ষা এড়াতে :) খুব ভাল পন্থা করা হয়েছে (যদিও আমি গত কয়েকদিন ধরে তাই উদ্বেগ নিয়ে এসও-তে প্রশ্নগুলি দেখছি যে লোকেরা এমনটি করে না তারা কী করছে তা সত্যিই বুঝতে পারুন তারা SFINAE কে সোনার হাতুড়ি হিসাবে ব্যবহার শুরু করেছে ... আপনার ক্ষেত্রে নয়, তবে আমি আশঙ্কা করি কোডটি আরও জটিল এবং বজায় রাখা শক্ত হয়ে উঠবে ...)
ডেভিড রডগ্রিজেজ - ড্রিবাস

11
@ ডেভিডরডগ্রিজেজ-ড্রিবিয়াস: :-) আমি কেবলমাত্র আধুনিক সি +++ এর সোনালি নিয়মটি অনুসরণ করছি: যদি কোনও কিছু টেম্পলেট নয় তবে নিজেকে জিজ্ঞাসা করুন, "এটি একটি টেম্পলেট কেন নয়?" তারপরে এটি একটি টেম্পলেট করুন।
জেমস ম্যাকনেলিস

4
[যে কেউ এই শেষ মন্তব্যটিকে খুব গুরুত্বের সাথে নেওয়ার আগে: এটি একটি রসিকতা। সাজানোর ...]
জেমস ম্যাকনেলিস

11

আপনি নিম্নলিখিত ব্যবহার করতে পারেন:

template <typename T>
size_t iconv (iconv_t i, const T inbuf)
{
   return iconv(i, const_cast<T>(inbuf));
}

void myfunc(void) {
  const char** ptr = // ...
  iconv(foo, ptr);
}

আপনি পাস করতে পারেন const char**এবং লিনাক্স / ওএসএক্স এ এটি টেম্পলেট ফাংশনটি দিয়ে যাবে এবং ফ্রিবিএসডি-তে এটি সরাসরি যাবে iconv

খসড়া: এটি এমন কলগুলিকে অনুমতি দেবে iconv(foo, 2.5)যা অসীম পুনরাবৃত্তিতে সংকলক রাখবে।


4
সুন্দর! আমি মনে করি যে এই সমাধানটির সম্ভাবনা রয়েছে: আমি ফাংশনটি কোনও সঠিক মিল না হলে কেবলমাত্র টেমপ্লেটটি নির্বাচন করতে ওভারলোড রেজোলিউশনের ব্যবহার পছন্দ করি। কাজ করতে, কিন্তু, const_castএকটি স্থানান্তরিত করা প্রয়োজন হবে add_or_remove_constযে মধ্যে digs T**কিনা সনাক্ত করতে Tহয় constএবং যোগ করতে অথবা উপযুক্ত পদ থেকে সরাতে যোগ্যতা। এটি যে সমাধানটি আমি দেখিয়েছি তার চেয়ে এটি এখনও অনেক বেশি সহজবোধ্য। কিছুটা কাজ করে, সমাধান ছাড়াই এটি সমাধান করা সম্ভব হতে পারে const_cast(অর্থাত্ আপনার স্থানীয় ভেরিয়েবল ব্যবহার করে iconv)।
জেমস ম্যাকনেলিস

আমি কিছু মিস করেছি? ক্ষেত্রে যেখানে আসলiconv নন-কনস্ট্যান্ট, তা Tঅনুমিত হয় না const char**, যার অর্থ প্যারামিটারটির inbufটাইপ আছে const T, যা const char **const, এবং iconvটেম্পলেটে কলটি কেবল নিজেকে কল করে? যেমন জেমস যদিও বলেছেন, প্রকারের উপযুক্ত পরিবর্তনের সাথে সাথে Tএই কৌশলটি কাজ করে এমন কোনও কিছুর ভিত্তি।
স্টিভ জেসপ

দুর্দান্ত, চতুর সমাধান। +1!
লিনাকোসিজ

7
#ifdef __linux__
... // linux code goes here.
#elif __FreeBSD__
... // FreeBSD code goes here.
#endif

এখানে আপনার কাছে সমস্ত অপারেটিং সিস্টেমের আইডিস রয়েছে। আমার জন্য এই সিস্টেমটি পরীক্ষা না করে অপারেটিং সিস্টেমের উপর নির্ভর করে এমন কিছু করার চেষ্টা করার কোনও અર્થ নেই। এটি সবুজ ট্রাউজার কিনার মতো তবে তাদের দিকে না তাকিয়ে।


14
তবে প্রশ্নকর্তা স্পষ্টতই বলেছেন without resorting to trying to detect the platform...
ফ্রেডেরিক হামিদী

4
@Linuxios: পর্যন্ত লিনাক্স বিক্রেতা বা Apple সিদ্ধান্ত নেন তারা কি অনুসরণ করতে চান POSIX মান । এই জাতীয় কোডিং বজায় রাখা কুখ্যাতভাবে কঠিন is
ফ্রেড ফু

4
@larsmans: লিনাক্স ও Mac OS X না মান অনুসরণ । আপনার লিঙ্কটি 1997 সালের It এটি পিছনে থাকা ফ্রিবিএসডি।
স্বপ্ন

4
@ লিনাক্সোস: না, এটি আরও ভাল নয়। আপনি যদি সত্যিই প্ল্যাটফর্ম চেক করতে চান তবে অটোকনফ বা একটি অনুরূপ সরঞ্জাম ব্যবহার করুন। অনুমানগুলি না করে আসল প্রোটোটাইপটি পরীক্ষা করুন যা কোনও সময়ে ব্যর্থ হবে এবং এটি ব্যবহারকারীর জন্য ব্যর্থ হবে।
মিশা গার্নি

4
@ মাইচাগার্নি: ভাল কথা। সত্যি বলতে, আমার এই প্রশ্নটি থেকে বের হওয়া উচিত। আমি এতে কোনও অবদান রাখতে সক্ষম বলে মনে হচ্ছে না।
লিনাকিনিওস

1

আপনি নির্দেশ করেছেন যে আপনার নিজের র‍্যাপার ফাংশনটি গ্রহণযোগ্য। আপনিও সতর্কতার সাথে বাঁচতে ইচ্ছুক বলে মনে করছেন।

সুতরাং, আপনার মোড়কে সি ++ তে লেখার পরিবর্তে এটি সিতে লিখুন, যেখানে আপনি কেবল কয়েকটি সিস্টেমে একটি সতর্কতা পাবেন:

// my_iconv.h

#if __cpluscplus
extern "C" {
#endif

size_t my_iconv( iconv_t cd, char **restrict inbuf, ?* etc... */);


#if __cpluscplus
}
#endif



// my_iconv.c
#include <iconv.h>
#include "my_iconv.h"

size_t my_iconv( iconv_t cd, char **inbuf, ?* etc... */)
{
    return iconv( cd, 
                inbuf /* will generate a warning on FreeBSD */,
                /* etc... */
                );
}

1

কেমন

static void Test(char **)
{
}

int main(void)
{
    const char *t="foo";
    Test(const_cast<char**>(&t));
    return 0;
}

সম্পাদনা: অবশ্যই, "প্ল্যাটফর্ম সনাক্ত না করে" কিছুটা সমস্যা is ওফস :-(

সম্পাদনা 2: ঠিক আছে, উন্নত সংস্করণ, সম্ভবত?

static void Test(char **)
{
}

struct Foo
{
    const char **t;

    operator char**() { return const_cast<char**>(t); }
    operator const char**() { return t; }

    Foo(const char* s) : t(&s) { }
};

int main(void)
{
    Test(Foo("foo"));
    return 0;
}

এর সাথে সমস্যাটি হ'ল অন্য প্ল্যাটফর্মে এটি সংকলন করবে না (যেমন ফাংশনটি গ্রহণ করলে const char**এটি ব্যর্থ হবে)
ডেভিড রদ্রিগেজ -

1

কি সম্পর্কে:

#include <cstddef>
using std::size_t;

// test harness, these definitions aren't part of the solution
#ifdef CONST_ICONV
    // other parameters removed for tediousness
    size_t iconv(const char **inbuf) { return 0; }
#else
    // other parameters removed for tediousness
    size_t iconv(char **inbuf) { return 0; }
#endif

// solution
template <typename T>
size_t myconv_helper(size_t (*system_iconv)(T **), char **inbuf) {
    return system_iconv((T**)inbuf); // sledgehammer cast
}

size_t myconv(char **inbuf) {
    return myconv_helper(iconv, inbuf);
}

// usage
int main() {
    char *foo = 0;
    myconv(&foo);
}

আমি মনে করি এটি সি ++ 03 তে কঠোর আলিয়াজিং লঙ্ঘন করেছে, তবে সি ++ 11 এ নয় কারণ সি ++ 11 const char**এবং char**তথাকথিত "একই ধরণের" রয়েছে। আপনি কোনও তৈরির পরিবর্তে অন্যের মতো কঠোর আলিয়াজিংয়ের লঙ্ঘন এড়াতে পারবেন না const char*, এটির সমান সেট করুন *foo, iconvঅস্থায়ীটিতে একটি পয়েন্টার দিয়ে কল করুন , তারপরে ফলাফলটি অনুলিপি করার *fooপরে const_cast:

template <typename T>
size_t myconv_helper(size_t (*system_iconv)(T **), char **inbuf) {
    T *tmpbuf;
    tmpbuf = *inbuf;
    size_t result = system_iconv(&tmpbuf);
    *inbuf = const_cast<char*>(tmpbuf);
    return result;
}

এটি দৃ const়তা-নির্ভুলতার POV থেকে নিরাপদ, কারণ সব iconv এটি করেinbuf তা এতে সঞ্চারিত পয়েন্টার বৃদ্ধি করে। সুতরাং আমরা পয়েন্টার থেকে প্রাপ্ত পয়েন্টার থেকে "কাস্টিং দূরে ফেলে দিচ্ছি" যেটি প্রথম দেখলাম non

আমরা একজন জমিদার লিখতে পারে myconvএবং myconv_helperযে নিতে const char **inbufঅন্যান্য দিক সম্পর্কে এবং messes, যার দরুন আহ্বানকারী একটি মধ্যে পাস করা হবে কিনা তা পছন্দ হয়েছে const char**বা char**। কোনটি যুক্তিযুক্তভাবে iconvC ++ এ প্রথম স্থানে কলকারীকে দেওয়া উচিত ছিল, তবে অবশ্যই ইন্টারফেসটি কেবল সি থেকে অনুলিপি করা হয়েছিল যেখানে কোনও ফাংশন ওভারলোডিং নেই।


"সুপার-পেডেন্ট্রি" কোডটি অপ্রয়োজনীয়। একটি বর্তমান stdlibc ++ সহ জিসিসি 4.7 এ, আপনাকে সংকলনের জন্য এটি দরকার
কনরাড রুডল্ফ

1

আপডেট: এখন আমি দেখতে পাচ্ছি যে এটি অটোটুল ছাড়াই সি ++ এ পরিচালনা করা সম্ভব, তবুও আমি এটি সন্ধানকারী লোকদের জন্য অটোকনফ সমাধানটি রেখে দিচ্ছি।

আপনি iconv.m4যা সন্ধান করছেন তা হ'ল gettext প্যাকেজ দ্বারা ইনস্টল করা।

আফিক্স এটি ঠিক:

AM_ICONV

কনফিগার.একে, এবং এটির সঠিক প্রোটোটাইপ সনাক্ত করা উচিত।

তারপরে, আপনি যে কোডটি ব্যবহার করছেন তাতে:

#ifdef ICONV_CONST
// const char**
#else
// char**
#endif

এটির জন্য টেমপ্লেট স্পেশালাইজেশন ব্যবহার করুন। উপরে দেখুন.
আলেকজান্ডার ওহ

4
ধন্যবাদ! আমি ইতিমধ্যে অটোটুলগুলি ব্যবহার করেছি এবং এটি সমস্যাটির চারপাশে কাজ করার মানক উপায় বলে মনে হচ্ছে, সুতরাং এটি নিখুঁত হওয়া উচিত! দুর্ভাগ্যক্রমে আমি আইকনভি.এম 4 ফাইলটি সন্ধান করতে অটোকনফ পেতে সক্ষম হইনি (এবং এটি ওএস এক্স-তে অটোটুলগুলির একটি প্রাচীন সংস্করণ রয়েছে বলে মনে হয় না), তাই আমি এটি পোর্টেবলভাবে কাজ করতে সক্ষম হইনি । চারপাশে গুগলিং দেখায় যে প্রচুর লোকেরা এই ম্যাক্রো নিয়ে সমস্যায় পড়ে। ওহ, অটোটুলগুলি!
হাস্যকর_ফিশ 21

আমি মনে করি আমার উত্তরে একটি কুরুচিপূর্ণ তবে ঝুঁকিপূর্ণ হ্যাক নেই। তবুও, আপনি যদি ইতিমধ্যে অটোকনফ ব্যবহার করছেন, এবং আপনার যত্ন নেওয়া প্ল্যাটফর্মগুলিতে প্রয়োজনীয় কনফিগারেশন উপস্থিত থাকলে, এটি ব্যবহার না করার কোনও আসল কারণ নেই ...
স্টিভ জেসপ

আমার সিস্টেমে .m4 ফাইলটি gettextপ্যাকেজ দ্বারা ইনস্টল করা আছে । এছাড়া, এটিও খুবই সাধারণ প্যাকেজ ব্যবহৃত ম্যাক্রো অন্তর্ভুক্ত করা জন্য m4/ডিরেক্টরি ও আছে ACLOCAL_AMFLAGS = -I m4এর মধ্যে Makefile.am। আমি মনে করি স্বনির্ধারণ এমনকি ডিফল্টরূপে ডিরেক্টরিতে এটি অনুলিপি করে।
মিশা গার্নি

0

আমি এই পার্টিতে দেরি করেছি তবে এখনও, আমার সমাধানটি এখানে:

// This is here because some compilers (Sun CC) think that there is a
// difference if the typedefs are not in an extern "C" block.
extern "C"
{
//! SUSv3 iconv() type.
typedef size_t (& iconv_func_type_1) (iconv_t cd, char * * inbuf,
    size_t * inbytesleft, char * * outbuf, size_t * outbytesleft); 


//! GNU iconv() type.
typedef size_t (& iconv_func_type_2) (iconv_t cd, const char * * inbuf,
    size_t * inbytesleft, char * * outbuf, size_t * outbytesleft);
} // extern "C"

//...

size_t
call_iconv (iconv_func_type_1 iconv_func, char * * inbuf,
    size_t * inbytesleft, char * * outbuf, size_t * outbytesleft)
{
    return iconv_func (handle, inbuf, inbytesleft, outbuf, outbytesleft);
}

size_t
call_iconv (iconv_func_type_2 iconv_func, char * * inbuf,
    size_t * inbytesleft, char * * outbuf, size_t * outbytesleft)
{
    return iconv_func (handle, const_cast<const char * *>(inbuf),
        inbytesleft, outbuf, outbytesleft);
}

size_t
do_iconv (char * * inbuf, size_t * inbytesleft, char * * outbuf,
    size_t * outbytesleft)
{
    return call_iconv (iconv, inbuf, inbytesleft, outbuf, outbytesleft);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.