Python C++ctypes在ubuntu中传递bool

Python C++ ctypes passing bool in ubuntu

本文关键字:bool ubuntu C++ctypes Python      更新时间:2024-09-30

我正试图通过将布尔值从C++代码传递回Python,将我的Python(3.7.6(代码链接到C++。我的操作系统是Ubuntu 16.04。C++的IDE是Visual Studio。

在运行Python包装器代码时,我收到消息:

libcppstring.so: undefined symbol: cpp_string

python代码、*.so文件等都在同一个目录中。c++代码是在终端提示下用编译的

g++ -O3 -Wall -Werror -shared -std=c++11 -fPIC -o libcppstring.so cpp_string.cpp  

我的python包装器代码、c++代码和头代码都非常简单。只想将两个字符串从Python传递到C++共享对象,并向Python返回"true"。也许我把编译命令的顺序搞砸了。

#---------python wrapper code------------------
import ctypes
import sys
import os
localPath = os.path.dirname(os.path.realpath(__file__))
sys.path.append(localPath)
if __name__ == "__main__":
# Load the shared library into c types.
c_lib = ctypes.CDLL(localPath+"/libcppstring.so")
# Sample data for our call:
string1 = "hello, "
string2 = "world"
c_lib.cpp_string.restype = ctypes.c_bool
answer = c_lib.cpp_string( string1, string2)
print(answer)

cpp代码:cpp_string.cpp

#include "cpp_string.h"
bool cpp_string( std::string string1, std::string string2){
/*use this to convert to const char* to use sqlite3 in c */
/*used once the code is working*/  
string1.c_str();
return (true);
}

头代码:cpp_string.h

#include <string>
#ifdef _MSC_VER
#define EXPORT_SYMBOL __declspec(dllexport)
#else
#define EXPORT_SYMBOL
#endif
EXPORT_SYMBOL bool cpp_string( std::string string1, std::string string2);

要将ctypes与C++接口,请使用具有C兼容类型的extern "C"函数。还要声明.argtypes(参数类型(和.restype(返回类型(,以便更好地进行错误检查。

test.cpp

#include <iostream>
#ifdef _WIN32
#   define API __declspec(dllexport)
#else
#   define API
#endif
extern "C" API
int cpp_string(const char* string1, const char* string2) {
std::cout << string1 << std::endl << string2 << std::endl;
return 1;
}

测试.py

import ctypes as ct
dll = ct.CDLL('./test')
dll.cpp_string.argtypes = ct.c_char_p,ct.c_char_p
dll.cpp_string.restype = ct.c_int
print(dll.cpp_string(b'Hello',b'World!'))

输出:

Hello
World!
1

注意,C中的char*在Python中是c_char_p,并且采用Pythonbytes类型参数。如果要传递Pythonstr类型参数,请使用wchar_t*/c_wchar_p

首先,非常感谢Tolonen先生。来自另一个社区和一个非常乐于助人的人(全部归功于J*M#(,我确实解决了我的问题。这是我的代码(我只想返回TRUE,它确实如此。

cppstring.h

#include <string>
#ifdef _MSC_VER
#define EXPORT_SYMBOL __declspec(dllexport)
#else
#define EXPORT_SYMBOL
#endif
extern "C" {
EXPORT_SYMBOL bool cppstring( std::string string1, std::string string2);
}

cppstring.cpp

#include <string>
#include "cppstring.h"
bool cppstring( std::string string1, std::string string2){
/*use this to convert to const char* to use sqlite3 in c */
string1.c_str();
return (true);
}

和,

cString_test.py

#!/usr/bin/env python
""" Simple examples of calling C functions through ctypes module. """
import ctypes
import sys
import os
localPath = os.path.dirname(os.path.realpath(__file__))
sys.path.append(localPath)
if __name__ == "__main__":
# Load the shared library into c types.
c_lib = ctypes.CDLL(localPath+"/libcppstring.so")
# Sample data for our call:
string1 = "hello, "
string2 = "world"
c_lib.cppstring.restype = ctypes.c_bool
answer = c_lib.cppstring( string1, string2)
print(answer)