कैसे सुपीरियर सरणियों को वेक्टर <int> & (संदर्भ) में SWIG के साथ परिवर्तित करें


10

मेरा लक्ष्य:

अजगर में 3 संख्यात्मक सारणी बनाएं (उनमें से 2 को विशिष्ट मूल्यों के साथ आरंभीकृत किया जाएगा), फिर उनमें से तीनों को सी + फंक्शन में सदिश संदर्भों के रूप में स्वाइप के माध्यम से भेजें (यह डेटा पर प्रतिलिपि बनाने और दक्षता खोने से बचने के लिए है)। एक बार c ++ फ़ंक्शन में, सरणियों में से 2 को जोड़ें और उनकी राशि को 3rd सरणी में डालें।

vec_ref.h

#include <vector>
#include <iostream>

void add_vec_ref(std::vector<int>& dst, std::vector<int>& src1, std::vector<int>& src2);

vec_ref.cpp

#include "vec_ref.h"
#include <cstring> // need for size_t
#include <cassert>

void add_vec_ref(std::vector<int>& dst, std::vector<int>& src1, std::vector<int>& src2) {
    std::cout << "inside add_vec_ref" << std::endl;
    assert(src1.size() == src2.size());
    dst.resize(src1.size());

    for (size_t i = 0; i < src1.size(); i++) {
        dst[i] = src1[i] + src2[i];
    }
}

vec_ref.i

%module vec_ref
%{
    #define SWIG_FILE_WITH_INIT
    #include "vec_ref.h"
%}

%include "numpy.i"
%init %{
import_array();
%}

%include "std_vector.i"
%template(vecInt) std::vector<int>;
// %template(vecIntRef) std::vector<int> &; 

// %apply (std::vector<int> * INPLACE_ARRAY1, int DIM1) {(std::vector<int> * dst, int a),(std::vector<int> * src1, int b),(std::vector<int> * src2, int c)};
// %apply (std::vector<int> * INPLACE_ARRAY1) {(std::vector<int> * dst),(std::vector<int> * src1),(std::vector<int> * src2)};
// %apply (std::vector<int> & INPLACE_ARRAY1) {(std::vector<int> & dst),(std::vector<int> & src1),(std::vector<int> & src2)};
// %apply (std::vector<int> & INPLACE_ARRAY1, int DIM1) {(std::vector<int> & dst, int a),(std::vector<int> & src1, int b),(std::vector<int> & src2, int c)};

%include "vec_ref.h"

makefile

all:
    rm -f *.so *.o *_wrap.* *.pyc *.gch vec_ref.py
    swig -c++ -python vec_ref.i
    g++ -O0 -g3 -fpic -c vec_ref_wrap.cxx vec_ref.h vec_ref.cpp -I/home/lmckeereid/tools/anaconda3/pkgs/python-3.7.3-h0371630_0/include/python3.7m/
    g++ -O0 -g3 -shared vec_ref_wrap.o vec_ref.o -o _vec_ref.so

tester.py

import vec_ref as vec
import numpy as np

a = np.array([1,2,3], dtype=np.intc)
b = np.array([4,5,6], dtype=np.intc)
c = np.zeros(len(a), dtype=np.intc)

print('---Before---\na:', a)
print('b:', b)
print('c:', c)

vec.add_vec_ref(c,a,b)

print('---After---\na:', a)
print('b:', b)
print('c:', c)

आउटपुट:

---Before---
a: [1 2 3]
b: [4 5 6]
c: [0 0 0]
Traceback (most recent call last):
  File "tester.py", line 12, in <module>
    vec.add_vec_ref(c,a,b)
TypeError: in method 'add_vec_ref', argument 1 of type 'std::vector< int,std::allocator< int > > &'

मैंने vec_ref.i में पाए गए सभी% लागू और% टेम्पलेट निर्देशों को टिप्पणी करने की कोशिश की है, लेकिन उन्होंने काम नहीं किया।

क्या कुछ टाइपमैप हैं जिन्हें मुझे शामिल करना चाहिए कि मैं नहीं हूं?


3
यह संभव नहीं है। C ++ में, आप केवल उन वस्तुओं के संदर्भ बना सकते हैं जो वास्तव में मौजूद हैं। हालांकि, सुन्न सरणियों में ए नहीं होता है std::vector
pschill

जवाबों:


3

मैं @pschill से सहमत हूं: डेटा कॉपी किए बिना एक std :: वेक्टर प्राप्त करना संभव नहीं है।

एक विकल्प std::spanक्लास टेम्पलेट का उपयोग करना है (C ++ 20 में पेश किया गया है), या spanलाइब्रेरी में परिभाषित समान क्लास टेम्पलेट।

एक बनाना std::span<int>एक प्रदान करेगा के मद्देनजर एक में मौजूद डेटा numpyसरणी, और प्रदान करते हैं कई सुविधाजनक सदस्य कार्यों (जैसे operator[], iterators, front(), back(), आदि) C ++।

स्पैन बनाना कभी भी अंपनी सरणी से डेटा कॉपी नहीं करेगा ।


मुझे जो सबसे अच्छा विकल्प प्रतीत होता है उसे प्रदान करने के लिए धन्यवाद (अपनी कक्षा बनाने से अलग)।
अन्यान्य

अगर मैं वास्तव में प्रतिलिपि के बिना मेरे C ++ फ़ंक्शन में एक std :: वेक्टर का उपयोग (और संशोधित) करना चाहता था, तो मेरे पास क्या विकल्प होंगे? रॉ सूचक को std :: वेक्टर? share_ptr to std :: वेक्टर?
गेब्रियल डेविलर्स

@ गैब्रिएलडेविलर्स, अगर मैं आपके प्रश्न को समझता हूं, यदि कोई वेक्टर मौजूद है और आप इसे अपने कार्य में संशोधित करना चाहते हैं, तो मैं वेक्टर के संदर्भ का उपयोग करने की सलाह दूंगा: std::vector<T>& v
निकोलसएम

@ नाइकोलासम मेरा मतलब एक एपीआई में है जो मैं SWIG का उपयोग करके लपेटना चाहता हूं। मैं पूछ रहा हूं क्योंकि मैं समझता हूं कि एसडब्ल्यूआईजी वैक्टरों के लिए नॉन-कॉस्ट संदर्भ नहीं लपेट सकता है।
गेब्रियल डेविलर्स

मुझे माफ करें। मेरा सुझाव है कि आप एक नया प्रश्न बनाएं जो आपके विशिष्ट मामले पर केंद्रित हो।
NicholasM

0

आप फ़ेसबुक लाइब्रेरी का उल्लेख कर सकते हैं, जो कि आप जो हासिल करना चाहते हैं, उसे और अधिक सुरुचिपूर्ण तरीके से प्राप्त कर सकते हैं।

अजगर-विशिष्ट: सुन्न सरणी <-> C ++ सूचक इंटरफ़ेस (वेक्टर)

आप इसके जीथूब पेज पर कोड देख सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.