无法在Python中将字符串传递给DLL函数的char *参数

0 投票
1 回答
643 浏览
提问于 2025-04-17 05:59

我正在尝试在Python中使用一个dll,使用的是ctypes库。因为我对这方面还很陌生,所以我开始查阅Python的文档。在成功加载dll后,当我试图将一个字符串传递给一个需要char *类型的函数时,出现了这样的错误:

“ValueError: 可能是调用时传入了太多参数(多了4个字节)”。

我也尝试查看其他帖子,但还是没能解决这个问题。

我尝试了不同的方法来传递这个字符串,比如使用byref()pointer(),但结果没有改变。我还尝试了WINFUNCTYPE,但也失败了。我使用的dll是windll。

这是我在Python中写的一个测试程序:

from ctypes import *

lpDLL=WinDLL("C:\some_path\myDll.dll")
print lpDLL

IP_ADDR = create_string_buffer('192.168.100.228')
#IP_ADDR = "192.168.100.228"
#IP_ADDR = c_char_p("192.168.100.228")

print IP_ADDR, IP_ADDR.value

D_Init=lpDLL.D_Init
D_InitTester=lpDLL.D_InitTester

#D_InitTesterPrototype = WINFUNCTYPE(c_int, c_char_p)
#D_InitTesterParamFlags = ((1, "ipAddress", None),)
#D_InitTester = d_InitTesterPrototype(("D_InitTester", lpDLL), D_InitTesterParamFlags)

try:
    D_Init()
    D_InitTester("192.168.100.254")
except ValueError, msg:
    print "Init_Tester Failed"
    print msg

这是D_InitTester在一个cpp文件中的实现,这个实现可以在dll导出中找到:

D_API int D_InitTester(char *ipAddress)
{
    int err = ERR_OK;

    if (LibsInitialized)
    {
        ...
        some code;
        ...

        else
        {
            err = hndl->ConInit(ipAddress);
        }

        if ( 0 < err )
        {
            err = ERR_NO_CONNECTION;
        }
        else
        {
        nTesters = 1;
            InstantiateAnalysisClasses();
            InitializeTesterSettings();
            if(NULL != hndl->hndlFm)
            {
                FmInitialized = true;
            }
        }
    }
    else
    {
        err = ERR_NOT_INITIALIZED;
    }
    return err;
}

非常感谢你的帮助。

1 个回答

2

这个错误最可能的原因是调用约定不匹配。我的猜测是,你的C++动态链接库(DLL)导出的函数使用的是cdecl约定,但你使用WinDLL时暗示使用的是stdcall

要使用cdecl,你可以这样创建你的库:

lpDLL=CDLL("C:\some_path\myDll.dll")

撰写回答