You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用C++ DLL:修改内存地址指向字符串的实现问题

问题分析与解决方案

核心错误点

  1. C++字符串修改逻辑错误:free_memory函数中(*memory_string) = "hello World !";是完全错误的写法——*memory_string是单个char类型,而右侧是字符串字面量(const char*),这会把指针的低8位赋值给字符串的第一个字符,根本无法修改整个字符串内容。
  2. 函数名误导:free_memory实际用于修改字符串,而非释放内存,命名混乱。
  3. 冗余参数:memory_string函数的size和pValues参数未被使用,属于无效代码。
  4. Python类型未显式声明:未指定DLL函数的参数和返回值类型,ctypes默认转换可能引发跨平台或类型不匹配问题。

修正后的C++ DLL代码

#include <cstring>
#include <cstdlib>

// 确保EXPORT_API是正确的导出宏,比如Windows下#define EXPORT_API __declspec(dllexport)
EXPORT_API void* create_string() {
    const char init_text[] = "hello world !";
    // 计算所需内存大小(含字符串终止符)
    size_t buf_size = strlen(init_text) + 1;
    char* string_buf = (char*)malloc(buf_size);
    
    if (string_buf != nullptr) {
        // 安全复制初始字符串
        strcpy_s(string_buf, buf_size, init_text);
    }
    return string_buf;
}

EXPORT_API void modify_string(void* str_ptr) {
    if (str_ptr == nullptr) return;
    
    char* target_str = static_cast<char*>(str_ptr);
    const char new_text[] = "hello World !";
    // 确保新字符串长度不超过原缓冲区大小(此处原缓冲区足够容纳)
    size_t new_text_size = strlen(new_text) + 1;
    // 安全覆盖原字符串
    strcpy_s(target_str, 14, new_text); // 14是原缓冲区的总大小(含终止符)
}

EXPORT_API void free_string(void* str_ptr) {
    if (str_ptr != nullptr) {
        free(static_cast<char*>(str_ptr));
    }
}

修正后的Python代码

import ctypes

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

# 显式声明DLL函数的参数和返回值类型
dll.create_string.argtypes = ()
dll.create_string.restype = ctypes.c_void_p

dll.modify_string.argtypes = (ctypes.c_void_p,)
dll.modify_string.restype = None

dll.free_string.argtypes = (ctypes.c_void_p,)
dll.free_string.restype = None

# 创建字符串内存块
str_address = dll.create_string()
print("修改前:", ctypes.cast(str_address, ctypes.c_char_p).value.decode("utf-8"))

# 修改字符串内容
dll.modify_string(str_address)
print("修改后:", ctypes.cast(str_address, ctypes.c_char_p).value.decode("utf-8"))

# 释放内存,避免泄漏
dll.free_string(str_address)

关键说明

  1. 字符串修改方式:必须使用strcpy_s(或strncpy)等字符串复制函数来覆盖原内存块的内容,不能直接给单个字符赋值字符串字面量。
  2. 内存安全:修改字符串时要确保原缓冲区大小足够容纳新字符串,否则会触发内存溢出。更严谨的做法是在创建内存时返回缓冲区大小,或让修改函数重新分配内存(此时需要返回新的指针地址,Python需更新指针变量)。
  3. 内存释放:必须调用free释放malloc分配的内存,避免内存泄漏。
  4. ctypes类型声明:显式指定argtypes和restype可以避免隐式类型转换错误,提升跨平台兼容性。

内容的提问来源于stack exchange,提问作者Bleu No

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 13:03:26