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

使用ctypes从C DLL向Python返回十六进制值遇数组访问异常求助

问题排查与修复方案

让我们一步步拆解你的代码问题,这些错误直接导致了返回值始终为-1或0:

1. 字符串比较错误(核心匹配失败原因)

在C++中,const char*类型用==比较的是指针地址,而不是字符串内容。你需要用C标准库的strcmp函数来判断字符串是否相等:

#include <cstring> // 必须包含这个头文件

// 替换原来的判断逻辑
if (strcmp(A1[i].name, needed_name) == 0) {
    // 匹配成功
}

2. 结构体成员访问错误

你的info_struct中style是数组类型(style_length style[MAX_SIZE]),不是指针,所以不能用->访问成员,需要用下标(比如取第一个元素style[0]):

// 原错误写法
// return A1[i].style->value;

// 修正后(假设你要取数组第一个元素的value)
return A1[i].style[0].value;

3. Python与C++函数名不匹配

你在C++中导出的函数是get_creation_data,但Python代码里调用的是get_section_data,这两个完全是不同的函数,导致调用失败返回默认值-1:

# 原错误代码
# valuell.get_section_data.argtypes = [c_char_p]
# valuell.get_section_data.restype = ct.c_int16
# return hex(valuell.get_creation_data(value_name))

# 修正后
valuell.get_creation_data.argtypes = [c_char_p]
valuell.get_creation_data.restype = ct.c_int16
return hex(valuell.get_creation_data(value_name.encode('utf-8'))) # 还要转字节串

4. 数组大小计算可能出错

你的代码中:

int A1_size = (A1size/ sizeof(A1[0])) ;

如果A1size已经是数组的元素个数(不是总字节数),那么这个计算完全错误,会导致循环次数远小于实际数组长度,直接跳过目标元素。此时应该直接用A1size作为循环上限:

// 如果A1size是元素个数
for (int i = 0; i < A1size; i++) {
    // ...
}

如果A1size是数组的总字节数,那当前计算是对的,但需要确认A1size的实际定义是否正确。

修正后的完整代码片段

Valuedll.cpp 关键部分修正

#include <iostream>
#include <string>
#include <array>
#include <cstring> // 新增头文件
#include "external_lists.h"

extern info_struct A1[];
extern info_struct A2[];
extern int A1size;
extern int A2size;

#define DLLEXPORT extern "C" __declspec(dllexport)

DLLEXPORT int get_creation_data(const char* needed_name){
    // 确认A1size的含义:如果是元素个数,直接用A1size;如果是字节数,用A1size/sizeof(A1[0])
    int A1_size = A1size; // 假设A1size是元素个数
    int A2_size = A2size;

    for (int i = 0; i < A1_size; i++) {
        if (strcmp(A1[i].name, needed_name) == 0) {
            // 取style数组第一个元素的value
            return A1[i].style[0].value;
        }
    }

    // 再遍历A2数组
    for (int i = 0; i < A2_size; i++) {
        if (strcmp(A2[i].name, needed_name) == 0) {
            return A2[i].style[0].value;
        }
    }

    return -1;
}

Python代码修正

import os, sys, re
from ctypes import *
import ctypes as ct

def get_creation_values(value_name):
    valuell = CDLL(r'C:\Documents\creation.dll') # 用原始字符串避免转义问题
    valuell.get_creation_data.argtypes = [c_char_p]
    valuell.get_creation_data.restype = ct.c_int16
    # 将Python字符串转为C兼容的字节串
    return hex(valuell.get_creation_data(value_name.encode('utf-8')))

if __name__ == "__main__":
    val = get_creation_values('LIMITING')
    print(val)

额外检查点

  • 确保external_lists.h中MAX_SIZE的定义是合理的,且A1数组中style元素确实有有效值。
  • 编译DLL时要确保A1、A2、A1size、A2size被正确导出,没有链接错误。
  • 如果style_length中的value是uint16_t,C++返回int是可以的,但要注意溢出问题(不过uint16_t最大值是65535,在int范围内)。

内容的提问来源于stack exchange,提问作者Armaja LaRue-Love

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:17:01