I'm trying to make a basic csv parser in c for a particular csv schema, and I'm trying to wrap the function for Python, but I keep getting a "StdVectorTraits not found" warning after wrapper generation. The wrapper is still able to be compiled using g , but when I try to import the underlying shared object using the object.py script, I get "ImportError: undefined symbol: _Z8myVectorRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"
This is the swig interface file:
%module parser;
%include "/usr/share/swig4.0/std/std_vector.i";
%include "/usr/share/swig4.0/std/std_iostream.i";
%include "/usr/share/swig4.0/std/std_sstream.i";
%include "/usr/share/swig4.0/std/std_string.i";
%include "/usr/share/swig4.0/std/std_basic_string.i";
%{
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>
std::vector<std::vector<double>> myVector(std::string&);
%}
%template(doubleVector) std::vector<double>;
%template(doubleVecVector) std::vector<std::vector<double>>;
std::vector<std::vector<double>> myVector(std::string& path)
{
std::ifstream file;
std::string read;
std::vector<std::vector<double>> data;
file.open(path);
for (int i = 0; i < 21; i )
{
std::getline(file, read);
}
for (int i = 0; i < 32; i )
{
std::vector<double> line;
std::getline(file, read);
std::stringstream ss(read);
for (int j = 0; j < 48; j )
{
std::getline(ss, read, ',');
line.push_back(std::stof(read));
}
data.push_back(line);
}
file.close();
return data;
}
Error:
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
/home/../test.ipynb Cell 1 in <cell line: 1>()
----> 1 import parser
File ~/../parser.py:15, in <module>
13 from . import _parser
14 else:
---> 15 import _parser
17 try:
18 import builtins as __builtin__
ImportError: /home/../_parser.so: undefined symbol: _Z8myVectorRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
CodePudding user response:
The function definition should be between %{
and %}
. Everything between %{/%}
is included directly in the generated wrapper. The function prototype should be at the end of the file after the %template
declarations to direct SWIG to generate a wrapper for that function.
Since the function body is in the wrong place it isn't defined hence the undefined symbol error.
Stripped down example:
test.i
%module test
%{
#include <vector>
std::vector<std::vector<double>> myVector()
{
return {{1.0,1.5},{2.0,2.5}};
}
%}
%include <std_vector.i>
%template(doubleVector) std::vector<double>;
%template(doubleVecVector) std::vector<std::vector<double>>;
std::vector<std::vector<double>> myVector();
Demo:
>>> import test
>>> test.myVector()
((1.0, 1.5), (2.0, 2.5))