ImportError: undefined symbol when importing swigged c++-class in python
ImportError: undefined symbol when importing swigged c++-class in python
我尝试使用 c++-class 在 Python 中进行套接字通信。因此,我创建了一个使用 nngpp 的 class。将 swigged 文件导入 python 时,我收到 ImportError: undefined symbol: nng_msg_insert。 class 的定义是:
/* 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;
}
};
swig 的接口文件是:
/* commclass.i */
%module commclass
%{
#include "src/commclass.h"
%}
%include "src/commclass.h"
然后我使用命令 python3 build_commclass.py build_ext --inplace
开始构建过程。文件build_commclass.py如下
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"]
)])
当我现在将 class 导入到 python 时,出现上述错误。我在 google 和 Whosebug 上搜索了很多,我很确定这是一个链接器问题。我还使用 distutils.core 的编译器和链接器选项尝试了很多不同的东西,但我没有找到解决方案。
编辑 1:
我现在将接口文件更改如下
/* 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"
我现在在 python 中导入时遇到相同的错误,但未定义的符号已更改。现在是 nng_aio_set_iov
。 nng_msg_insert
和 nng_aio_set_iov
都在我现在包含的文件 nng.h 中定义。我现在很困惑。
SWIG 默认只为 %include
直接指定的定义生成接口。 nng_msg_insert
未在 src/commclass.h
中定义。您需要额外的 %include
语句来引入定义。
请注意,您可以将默认值更改为使用 -includeall
SWIG 标志递归到所有 #include
语句,但您通常不希望整个 <iostream>
、<cstdio>
, <string>
, 等接口被包装,如果不付出很多额外的努力,它可能无法工作。
我尝试使用 c++-class 在 Python 中进行套接字通信。因此,我创建了一个使用 nngpp 的 class。将 swigged 文件导入 python 时,我收到 ImportError: undefined symbol: nng_msg_insert。 class 的定义是:
/* 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;
}
};
swig 的接口文件是:
/* commclass.i */
%module commclass
%{
#include "src/commclass.h"
%}
%include "src/commclass.h"
然后我使用命令 python3 build_commclass.py build_ext --inplace
开始构建过程。文件build_commclass.py如下
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"]
)])
当我现在将 class 导入到 python 时,出现上述错误。我在 google 和 Whosebug 上搜索了很多,我很确定这是一个链接器问题。我还使用 distutils.core 的编译器和链接器选项尝试了很多不同的东西,但我没有找到解决方案。
编辑 1: 我现在将接口文件更改如下
/* 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"
我现在在 python 中导入时遇到相同的错误,但未定义的符号已更改。现在是 nng_aio_set_iov
。 nng_msg_insert
和 nng_aio_set_iov
都在我现在包含的文件 nng.h 中定义。我现在很困惑。
SWIG 默认只为 %include
直接指定的定义生成接口。 nng_msg_insert
未在 src/commclass.h
中定义。您需要额外的 %include
语句来引入定义。
请注意,您可以将默认值更改为使用 -includeall
SWIG 标志递归到所有 #include
语句,但您通常不希望整个 <iostream>
、<cstdio>
, <string>
, 等接口被包装,如果不付出很多额外的努力,它可能无法工作。