কোনও আরসিপিপি ফাংশন থেকে poin নতুন` অবজেক্টে পয়েন্টার ফেরত দেওয়ার উপযুক্ত উপায়


9

1) সম্ভাব্য বৃহত মেমরি প্রিন্ট সহ একটি কাস্টম শ্রেণি এবং 2) একটি শীর্ষ-স্তরের ফাংশন যা কিছু প্রাক প্রসেসিং সম্পাদন করে, তারপরে আমাদের কাস্টম শ্রেণীর একটি নতুন অবজেক্ট তৈরি করে এবং ফেরত দেয়। মান দ্বারা অপ্রয়োজনীয় অনুলিপি এড়ানোর জন্য, ফাংশনটি বস্তুকে বরাদ্দ দেয় এবং পরিবর্তে এটিতে একটি পয়েন্টার দেয় returns

পূর্ববর্তী আলোচনার ভিত্তিতে , মনে হয় সদ্য তৈরি হওয়া কোনও বস্তুতে পয়েন্টার ফিরিয়ে দেওয়ার সঠিক উপায়টি এটি দিয়ে মোড়ানো Rcpp::XPtr<>। যাইহোক, আর এরপরে এটিকে কার্যকরভাবে হিসাবে দেখবে externalptrএবং আমি আধুনিক RCPP_EXPOSED_CLASSও কাজের RCPP_MODULEপদ্ধতিতে এটি কাস্ট করার সঠিক উপায় খুঁজে পেতে লড়াই করছি ।

বিকল্পটি হল কাঁচা পয়েন্টারটি ফিরিয়ে দেওয়া। তবে আমি 100% নির্দিষ্ট নই যে অবজেক্টের মেমরিটি সঠিকভাবে পরিষ্কার হয়ে যায়। আমি valgrindমেমরি ফাঁস পরীক্ষা করার জন্য দৌড়েছি , কিন্তু এটির কোনও সন্ধান পেল না। তবে কে সাফ করে? আর?

test.cpp

#include <Rcpp.h>

// Custom class
class Double {
public:
  Double( double v ) : value(v) {}
  double square() {return value*value;}
private:
  double value;
};

// Make the class visible
RCPP_EXPOSED_CLASS(Double)

// Option 1: returning raw pointer
Double* makeDouble( double x ) {
  Double* pd = new Double(x);
  return pd;
}

// Option 2: returning XPtr<>
SEXP makeDouble2( double x ) {
  Double* pd = new Double(x);
  Rcpp::XPtr<Double> ptr(pd);
  return ptr;
}

RCPP_MODULE(double_cpp) {
  using namespace Rcpp;

  function( "makeDouble", &makeDouble );
  function( "makeDouble2", &makeDouble2 );

  class_<Double>("Double")
    .constructor<double>("Wraps a double")
    .method("square", &Double::square, "square of value")
    ;
}

আর

Rcpp::sourceCpp("test.cpp")
d1 <- makeDouble(5.4)     # <-- who cleans this up???
# C++ object <0x56257d628e70> of class 'Double' <0x56257c69cf90>
d1$square()
# 29.16

d2 <- makeDouble2(2.3)
# <pointer: 0x56257d3c3cd0>
d2$square()
# Error in d2$square : object of type 'externalptr' is not subsettable

আমার প্রশ্নটি হল যে Rcpp::Xptr<>পয়েন্টারগুলি ফেরানোর উপযুক্ত উপায় কিনা এবং যদি তাই হয়, তবে আমি কীভাবে আর দেখতে পাব, ফলাফলটি Doubleনয় externalptr? বিকল্পভাবে, যদি কোনও কাঁচা পয়েন্টার ফিরিয়ে দেওয়া মেমরির সমস্যার কারণ না করে তবে ফাংশনটি তৈরি করে এমন বস্তু কে সাফ করে?


হ্যাঁ, আপনি সম্ভবত Rcpp::XPtrসি ++ কোড থেকে একটি বাহ্যিক পয়েন্টার তৈরি করতে চান । এবং আপনি এটি করতে চান double *বা আপনার পেডলোড যা-ই হোক না কেন cast এখানে গ্যালারিতে, গিটহাবের উদাহরণ থাকতে হবে ... একটি অনুপ্রাণিত অনুসন্ধানের সাহায্যে আপনি যথেষ্ট পরিমাণে কিছু খুঁজে পেতে পারেন?
ডার্ক এডেলবুয়েটেল

হাই @ ডিরকএডেলবুয়েটেল কাস্টটি সত্যই হওয়া দরকার CustomClass*। আসল অ্যাপ্লিকেশন হ'ল একটি কাস্টম ডেটা স্ট্রাকচার যা কোনও আর সমতুল্য নয় এবং সমস্ত ইন্টারঅ্যাকশনগুলি দ্বারা প্রকাশিত কার্যকারিতার মাধ্যমে সম্পন্ন হয় RCPP_MODULE। আমার অনুপ্রাণিত অনুসন্ধানের সন্ধান পাওয়া সবচেয়ে নিকটতম মিলটি 7 বছর আগের একটি পোস্ট ছিল যেখানে মনে হয় যে আমার কোনও template <> CustomClass* as()রূপান্তরকারী সংজ্ঞায়িত করা দরকার । তবে এটির সাথে কীভাবে ইন্টারঅ্যাক্ট করা উচিত RCPP_MODULEএবং RCPP_EXPOSED_CLASSআমি বিশেষত যেহেতু আমি ভেবেছিলাম যে পরেরটি ইতিমধ্যে সংজ্ঞায়িত হয়েছে wrap()এবং as()
আর্টেম সোকোলভ

একই থ্রেড থেকে রোমেনের পোস্টটিও খুব সহায়ক, তবে দুর্ভাগ্যক্রমে এটি পয়েন্টারগুলি পরিচালনা করার পরিবর্তে অবজেক্টের ব্যবহারকে সরাসরি হাইলাইট করে।
আর্টেম সোকলোভ

1
আমি জানি আমি অনুরূপ স্টাফগুলি করেছি তবে এখন আমি নিশ্চিত নই যে এটির সেরা উদাহরণটি। আপনি পরিষ্কারভাবে একটি 'সিঙ্গলটন' অবজেক্ট সেটআপ করতে পারেন এবং মডিউল (আরসিপিপিডিস) হিসাবে মোড়ানো করতে পারেন; আমি মনে করি আপনি আগের দুটি বা দুটি চাকরিতে যা বর্ণনা করেছেন তা আমি করেছি তবে আমি এখন একটি ভাল পাবলিক উদাহরণটি ভাবতে পারি না। তারপরে আবার - বিভিন্ন ডাটাবেস মোড়ক এবং অ্যাক্সেস প্যাকেজ এটি করে। সবচেয়ে ছোট বিষয় নয়, তাই সম্ভবত কোনও খেলনা / উপহাস বাস্তবায়ন দিয়ে শুরু করুন এবং সেখান থেকে তৈরি করুন?
ডার্ক এডেলবুয়েটেল

ব্যবহার RCPP_EXPOSED_CLASSএবং RCPP_MODULEএটি করার উপায় কি? আমি এর আগে কখনও ব্যবহার বা দেখিনি।
এফ। প্রিভি

উত্তর:


7

আমি মনে করি এটি পৃথক পৃথক পদ্ধতির দিকে তাকানো বোধগম্য। এটি পার্থক্য পরিষ্কার করে তোলে। দ্রষ্টব্য যে এটি আরসিপিপি মডিউলগুলি উইগনেটে আলোচনার সাথে বেশ মিল।

যখন Rcpp::XPtrআপনার ক্লাস থাকে এবং আপনি যে পদ্ধতিটি প্রকাশ করতে চান তার জন্য রফতানি করা সি ++ ফাংশন সরবরাহ করার সময়:

#include <Rcpp.h>

// Custom class
class Double {
public:
    Double( double v ) : value(v) {}
    double square() {return value*value;}
private:
    double value;
};

// [[Rcpp::export]]
Rcpp::XPtr<Double> makeDouble(double x) {
    Double* pd = new Double(x);
    Rcpp::XPtr<Double> ptr(pd);
    return ptr;
}

// [[Rcpp::export]]
double squareDouble(Rcpp::XPtr<Double> x) {
    return x.get()->square();
}

/***R
(d2 <- makeDouble(5.4))
squareDouble(d2)
*/

আউটপুট:

> Rcpp::sourceCpp('59384221/xptr.cpp')

> (d2 <- makeDouble(5.4))
<pointer: 0x560366699b50>

> squareDouble(d2)
[1] 29.16

দ্রষ্টব্য যে আর-তে বস্তুটি কেবল একটি "পয়েন্টার"। আপনি আরও ভাল কিছু চাইলে আপনি আর পাশের একটি এস 4 / আরসি / আর 6 / ... ক্লাস যুক্ত করতে পারেন।

আর সাইডের কোনও শ্রেণিতে বাহ্যিক পয়েন্টারটি মোড়ানো এমন কিছু যা আপনি আরসিপিপি মডিউলগুলি ব্যবহার করে নিখরচায় পাবেন:

#include <Rcpp.h>

// Custom class
class Double {
public:
    Double( double v ) : value(v) {}
    double square() {return value*value;}
private:
    double value;
};

RCPP_MODULE(double_cpp) {
    using namespace Rcpp;

    class_<Double>("Double")
        .constructor<double>("Wraps a double")
        .method("square", &Double::square, "square of value")
    ;
}

/***R
(d1 <- new(Double, 5.4))
d1$square()
*/

আউটপুট:

> Rcpp::sourceCpp('59384221/modules.cpp')

> (d1 <- new(Double, 5.4))
C++ object <0x560366452eb0> of class 'Double' <0x56036480f320>

> d1$square()
[1] 29.16

এটি সি ++ তে কনস্ট্রাক্টরের পরিবর্তে ফ্যাক্টরি পদ্ধতিটি ব্যবহার করতে সমর্থিত তবে আর দিকে অভিন্ন ব্যবহার সহ:

#include <Rcpp.h>

// Custom class
class Double {
public:
    Double( double v ) : value(v) {}
    double square() {return value*value;}
private:
    double value;
};

Double* makeDouble( double x ) {
    Double* pd = new Double(x);
    return pd;
}

RCPP_MODULE(double_cpp) {
    using namespace Rcpp;

    class_<Double>("Double")
        .factory<double>(makeDouble, "Wraps a double")
        .method("square", &Double::square, "square of value")
    ;
}

/***R
(d1 <- new(Double, 5.4))
d1$square()
*/

আউটপুট:

> Rcpp::sourceCpp('59384221/modules-factory.cpp')

> (d1 <- new(Double, 5.4))
C++ object <0x5603665aab80> of class 'Double' <0x5603666eaae0>

> d1$square()
[1] 29.16

অবশেষে, RCPP_EXPOSED_CLASSউপকারে আসে যদি আপনি Rcpp মডিউল সঙ্গে একটি আর পাশ কারখানা ফাংশন একত্রিত করতে চান যেহেতু এই সৃষ্টি Rcpp::asএবং Rcpp::wrapপাস করা প্রয়োজন এক্সটেনশন বস্তু R ও সি মধ্যে একটি ঘোষণা ব্যাক ++,। functionআপনি যেমনটি করেছিলেন বা আরসিপিপি বৈশিষ্ট্যগুলি ব্যবহার করে কারখানাটি রফতানি করা যায় যা আমি আরও প্রাকৃতিক বলে মনে করি:

#include <Rcpp.h>

// Custom class
class Double {
public:
    Double( double v ) : value(v) {}
    double square() {return value*value;}
private:
    double value;
};

// Make the class visible
RCPP_EXPOSED_CLASS(Double)

// [[Rcpp::export]]
Double makeDouble( double x ) {
    Double d(x);
    return d;
}

RCPP_MODULE(double_cpp) {
    using namespace Rcpp;

    class_<Double>("Double")
        .method("square", &Double::square, "square of value")
    ;
}

/***R
(d1 <- makeDouble(5.4))
d1$square()
*/

আউটপুট:

> Rcpp::sourceCpp('59384221/modules-expose.cpp')

> (d1 <- makeDouble(5.4))
C++ object <0x560366ebee10> of class 'Double' <0x560363d5f440>

> d1$square()
[1] 29.16

পরিষ্কার-পরিচ্ছন্নতার বিষয়ে: উভয় Rcpp::XPtrএবং আরসিপিপি মডিউলই একটি ডিফল্ট ফাইনালাইজারকে নিবন্ধভুক্ত করে যা বস্তুর ডেস্ট্রাক্টরকে ডাকে calls প্রয়োজনে আপনি একটি কাস্টম ফাইনালাইজার যুক্ত করতে পারেন।

আমি এই পদ্ধতির একটির জন্য একটি সুপারিশ দেওয়া কঠিন বলে মনে করি। সম্ভবত এগুলির প্রত্যেককে কিছু সাধারণ উদাহরণে চেষ্টা করা এবং আপনি কী ব্যবহার করতে আরও প্রাকৃতিক বলে মনে করেন তা দেখার পক্ষে ভাল।


2
খুব সুন্দর জিনিস। আপনি এখানে একটি রোল হয়।
ডার্ক এডেলবুয়েটেল

ধন্যবাদ. এটি অত্যন্ত সহায়ক! আমার মনে factoryহয় আমি যে মূল সংযোগকারীটি হারিয়েছি তা হ'ল।
আর্টেম সোকলভ

একটি ছোট্ট ফলোআপ হিসাবে, আপনি কি functionচূড়ান্তকরণকারীর নিবন্ধন করে তা জানবেন , নাকি এটি কেবল factory ?
আর্টেম সোকোলভ

1
@ আর্টেমসোকলভ আফাইক ডিফল্ট চূড়ান্তকরণকারীকে ডেকেছেন যে ডেস্ট্রাক্টর দ্বারা উত্পাদিত হয় class_<T>এবং কীভাবে এটি তৈরি হয় তার থেকে পৃথক।
রাল্ফ স্টুবনার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.