I try to use a c++-class for socket communication in Python. Therefore, I created a class that uses nngpp . When importing the swigged file to python, I get the ImportError: undefined symbol: nng_msg_insert. The definition of the class is:
/* commclass.h */
#include <nngpp/nngpp.h>
#include <nngpp/protocol/req0.h>
#include <nngpp/protocol/rep0.h>
#include <nngpp/msg_body.h>
#include <nngpp/msg_header.h>
#include <nngpp/msg.h>
#include <nngpp/socket.h>
#include <nngpp/view.h>
#include <string>
#include <nlohmann/json.hpp>
//#include <thread>
#include <iostream>
#include <cstdio>
#include "/usr/local/include/nng/nng.h"
//#include <memory>
#include <chrono>
using json = nlohmann::json;
class CommIF
{
private:
nng::socket socket;
nng::msg message;
int msg_size;
public:
CommIF(const std::string option, std::string ipToListen, std::string ipToDial)
{
message = nng::make_msg(0);
if (option.compare("rep") == 0)
{
socket = std::move(nng::rep::v0::open());
}
else if (option.compare("req") == 0)
{
socket = std::move(nng::req::v0::open());
}
else
{
printf("EXCEPTION");
}
socket.listen(ipToListen.c_str());
bool connected = false;
while (connected == false)
{
try
{
socket.dial(ipToDial.c_str());
connected = true;
std::cout << "successfully connected\n";
}
catch (const nng::exception &e)
{
std::cerr << e.what() << "; retry in 1 s" << '\n';
//std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
msg_size = 0;
}
};
The interface file for swig is:
/* commclass.i */
%module commclass
%{
#include "src/commclass.h"
%}
%include "src/commclass.h"
I then start with the command python3 build_commclass.py build_ext --inplace
the build process. The file build_commclass.py is the following
from distutils.core import setup, Extension
import os
name = "commclass"
version = "0.0.1"
os.environ["CC"] = "g++"
setup(name = name, version = version, ext_modules = [Extension(
name = '_commclass',
sources = ["commclass.i"],#"src/commclass.h"],
include_dirs = ['src'],#'/home/user1/Documents/extLibs','/usr/local/include'],
swig_opts = ["-c++", "-modern"]
)])
When I now import the the class to python, I get the error mentioned above. I searched a lot on google and stackoverflow and I am quite sure this is a linker issue. I also tried a lot of different things with the compiler and linker options of distutils.core, but I didn't find a solution.
Edit 1: I now changed the interface file as following
/* commclass.i */
/* module*/
%module commclass
%{
#include "/usr/local/include/nng/nng.h"
#include "src/nngpp/nngpp.h"
#include "src/nngpp/protocol/req0.h"
#include "src/nngpp/protocol/rep0.h"
#include "src/nngpp/socket.h"
#include "src/nngpp/msg.h"
#include "src/nngpp/aio.h"
#include "src/nngpp/aio_view.h"
#include "src/nngpp/msg_body.h"
#include "src/nngpp/msg_header.h"
#include "src/commclass.h"
%}
%include "/usr/local/include/nng/nng.h"
%include "src/commclass.h"
I now get the same error when importing in python, but the undefined symbol changed. It is now nng_aio_set_iov
. Both nng_msg_insert
and nng_aio_set_iov
are defined in the file nng.h which I have now included. I am confused now.
SWIG only generates interfaces for definitions that are directly specified by %include
by default. nng_msg_insert
is not defined in src/commclass.h
. You need additional %include
statements to bring in the definition.
Note you can change the default to recurse into all #include
statements with the -includeall
SWIG flag, but you generally don't want the entire <iostream>
, <cstdio>
, <string>
, etc. interfaces to be wrapped and it likely won't work without a lot of additional effort.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.