简体   繁体   中英

Using a C++ DLL in Python

So here I have a function in my DLL in C++ which allows to create a memory block with a string and which returns its memory address. Then from my python code I send this memory address to my 2nd function in C++ and I would like to modify the string from this address, but I can't.

How can I do it?

My C++ DLL

EXPORT_API void* memory_string(int size, int* pValues)  {
    const char text[] = "hello world !";

    size_t malloc_allocation_size = strlen(text) + 1;
    char* text_allocation = (char*)malloc(malloc_allocation_size * sizeof(char));

    strcpy_s(text_allocation, malloc_allocation_size, text);

    //uintptr_t address = reinterpret_cast<uintptr_t>(text_allocation);

    return static_cast<void*>(text_allocation);
}

EXPORT_API void free_memory(unsigned long long ptr)
{
    char* memory_string = reinterpret_cast<char*>(ptr);
    uintptr_t* memory_address = reinterpret_cast<uintptr_t*>(ptr);

    (*memory_string) = "hello World !";
}

My python code

import ctypes

DLL_PATH = "./RayDLL.dll"
LOAD_DLL = ctypes.cdll.LoadLibrary(DLL_PATH)

INT_POINTER = ctypes.POINTER(ctypes.c_int)

hex_array = ['0x72', '0x7c', '0x75', '0x65', '0x7e', '0x7f', '0x3d', '0x24', '0x25', '0x23', '0x24', '0x25', '0x23', '0x29']
size_array = len(hex_array) + 1

memory_string_function = LOAD_DLL.memory_string
memory_string_function.argtypes = (ctypes.c_int, INT_POINTER)
memory_string_function.restype = ctypes.c_void_p

int_array = ( ctypes.c_int * size_array )(*(int(_, base=16) for _ in hex_array) )
x = LOAD_DLL.memory_string(size_array, ctypes.cast(int_array, INT_POINTER))

#print(x)
print(ctypes.cast(x, ctypes.c_char_p).value)

LOAD_DLL.free_memory(ctypes.c_ulonglong(x))

print(ctypes.cast(x, ctypes.c_char_p).value)

Your first function memory_string is very weird. You don't even use the function input parameters. Secondly, your function free_memory should also take a void* not a long long unsigned. At least use size_t, not long long unsigned for storing a pointer.

(*memory_string) = "hello World !"; should not even compile in modern C++. "hello World !" is a string literal and you can think of it as array [h, e, l, ..., \0] stored in some imaginary place "literal area". This memory area is not yours, so you are not allowed to change it. You can only read it. Thus "hello World!" is const. However memory_string is not const. You cannot assign a const type/object to a non-const type/object. It would be possible to rewrite it like:

char* my_literal = "hello World!";
(*memory_string) = *my_literal ;

But please don't! This may not work, due to complicated rules for "pointer decay". Also this is all really messy, because my_literal could have larger size, than the allocated memory of memory_string.

Replace the assignment

(*memory_string) = "hello World !"

by strcpy or even better strcpy_s . strcopy_s forces you to specify the destination buffer size.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM