I am able to return a string after it is converted to a char*
.
import ctypes
from subprocess import Popen, PIPE
# Press the green button in the gutter to run the script.
libname = "c:\temp\debug_api_lib.dll"
c_lib = ctypes.windll.LoadLibrary(libname)
class Gilad(object):
def __init__(self, host, port):
c_lib.menu_function_new.argtypes = [ctypes.c_char_p, ctypes.c_int]
c_lib.menu_function_new.restype = ctypes.c_void_p
c_lib.get_mac_address_new.argtypes = [ctypes.c_void_p]
c_lib.get_mac_address_new.restype = ctypes.c_char_p
c_lib.get_otp_data_new.argtypes = [ctypes.c_void_p]
c_lib.get_otp_data_new.restype = (ctypes.c_char_p * 3)
self.obj = c_lib.menu_function_new(host, port)
def get_mac_address(self):
return c_lib.get_mac_address_new(self.obj)
def get_otp_data(self):
return c_lib.get_otp_data_new(self.obj)
if __name__ == '__main__':
host = "11.11.11.11".encode('utf-8')
t = Gilad(host, 21)
print(t.get_mac_address())
otp_data: object = t.get_otp_data()
for i in otp_data: //the issue is here
print(i)
Here is my cpp code wrapped with c-style:
extern "C"
{
__declspec(dllexport) menu_function* menu_function_new(char * host, int port)
{
return new menu_function(host, port);
}
__declspec(dllexport) char* get_mac_address_new(menu_function* menu_function)
{
std::string res_string = menu_function->get_mac_address();
char* res = new char[res_string.size()];
res_string.copy(res, res_string.size(), 0);
res[res_string.size()] = '\0';
return res;
}
__declspec(dllexport) char** get_otp_data_new(menu_function* menu_function)
{
int num = 3;
std::vector<std::string> res_string = menu_function->get_otp_data();
char** res = (char**)malloc(num * sizeof(char**));
for (int i = 0; i < num; i )
{
res[i] = (char*)malloc(res_string[i].size());
res_string[i].copy(res[i], res_string[i].size(), 0);
res[i][res_string[i].size()] = '\0';
}
return res;
}
I can see in res
the 3 strings being copied correctly, but when printing in python I get: b'\xa0y\xa4P\x12\x01'
I guess I am printing the pointers.
CodePudding user response:
The function is returning a char**
, and you've told Python that it is returning a char*[3]
(an array of 3 char*
pointers, not a pointer itself), so the returned value isn't being interpreted properly by ctypes.
Change the return type to ctypes.POINTER(ctypes.c_char_p)
, or alternatively change your program to return something that has the same size as char*[3]
, like std::array<char*, 3>
or struct otp_data { char *one, *two, *three; };
(which would be 1 less malloc since you can return this by value)