我正在研究从Python调用C ++代码。我刚刚了解了ctypes,并在网上看到了一些例子。我试图调用一个类似于以下内容的C ++函数:
get_data(re * data_record, char * string)
对c ++一无所知,我会问一些基础知识。 应该如何使用ctypes从python调用这样的函数。 我已经决定退后一步,因为我觉得我在这里错过了一些基本原则。
事实上,对于任何采用string类型的参数并返回整数的C ++函数,请参阅一些示例
struct db_obj {
char db_name[50],
int_32 db_guid,
char db_path[100];
};
get_database_running_status(db *db_obj,int_8 db_id,int_8 *retvalue);
get_database_running_status_string(db *db_obj,int_8 db_id,char *retvalue);
此函数将返回一个状态值(retvalue),我可以解码它以了解数据库的状态,例如10 =正常运行,11 = stropped,12 =暂停,404 =故障等。
虽然get_database_running_status_string将返回字符串而不仅仅是数字
我该怎么称呼这些?不知道那个*符号是什么,尽管我希望它有所帮助。
也许一旦我理解了如何从python正确调用C ++函数,那么我的问题可能会自行解决。
答案 0 :(得分:0)
发布工作C ++代码的实际示例会有所帮助,但我只是创建类似于演示的东西。
这是一个简短的C ++ DLL源代码。由于ctypes
包含C函数而不是C ++,因此函数被声明为extern "C"
才能正常工作。我在Windows上执行此操作,因此__declspec(dllexport)
用于将函数标记为从DLL导出:
#include <stdio.h>
struct record {
int x,y;
};
typedef int int_32;
typedef char int_8;
struct db_obj {
char db_name[50];
int_32 db_guid;
char db_path[100];
};
extern "C" {
__declspec(dllexport) void get_data_int(record* pRec, int* pResult) {
*pResult = pRec->x + pRec->y;
};
__declspec(dllexport) void get_data_string(record* pRec, char* pResult, size_t size) {
sprintf_s(pResult,size,"%d + %d = %d\n", pRec->x, pRec->y, pRec->x + pRec->y);
}
__declspec(dllexport) void get_database_running_status(db_obj* db, int_8 db_id, int_8 *retvalue) {
printf("db_name = %s\ndb_guid = %d\ndb_path = %s\ndb_id = %d\n", db->db_name, db->db_guid, db->db_path, db_id);
*retvalue = 42;
}
}
这是ctypes
包装器:
#!python2
import ctypes as c
class Record(c.Structure):
_fields_ = [('x',c.c_int),('y',c.c_int)]
class db_obj(c.Structure):
_fields_ = [('db_name',c.c_char * 50),
('db_guid',c.c_int),
('db_path',c.c_char * 100)]
dll = c.CDLL('x')
get_data_int = dll.get_data_int
get_data_int.argtypes = [c.POINTER(Record), c.POINTER(c.c_int)]
get_data_int.restype = None
get_data_string = dll.get_data_string
get_data_string.argtypes = [c.POINTER(Record), c.POINTER(c.c_char), c.c_size_t]
get_data_string.restype = None
get_database_running_status = dll.get_database_running_status
get_database_running_status.argtypes = [c.POINTER(db_obj), c.c_int8, c.POINTER(c.c_int8)]
get_database_running_status.restype = None
result = c.c_int()
rec = Record(5,7)
get_data_int(c.byref(rec),c.byref(result))
print(result.value)
result = c.create_string_buffer(50)
rec = Record(5,7)
get_data_string(c.byref(rec),result,c.sizeof(result))
print(result.value)
result = c.c_int8()
db = db_obj('database name',1234,'database path')
get_database_running_status(c.byref(db),7,c.byref(result))
print(result.value)
输出:
12
5 + 7 = 12
db_name = database name
db_guid = 1234
db_path = database path
db_id = 7
42
有关详细信息,请参阅ctypes文档。