Python 和 ctypes:如何将“指针到指针”正确传递到 DLL 中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4213095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 14:47:44  来源:igfitidea点击:

Python and ctypes: how to correctly pass "pointer-to-pointer" into DLL?

pythonctypes

提问by grigoryvp

I have a DLL that allocates memory and returns it. Function in DLL is like this:

我有一个分配内存并返回它的 DLL。DLL 中的函数是这样的:

void Foo( unsigned char** ppMem, int* pSize )
{
  * pSize = 4;
  * ppMem = malloc( * pSize );
  for( int i = 0; i < * pSize; i ++ ) (* ppMem)[ i ] = i;
}

Also, i have a python code that access this function from my DLL:

另外,我有一个从我的 DLL 访问这个函数的 python 代码:

from ctypes import *
Foo = windll.mydll.Foo
Foo.argtypes = [ POINTER( POINTER( c_ubyte ) ), POINTER( c_int ) ]
mem = POINTER( c_ubyte )()
size = c_int( 0 )
Foo( byref( mem ), byref( size ) ]
print size, mem[ 0 ], mem[ 1 ], mem[ 2 ], mem[ 3 ]

I'm expecting that printwill show "4 0 1 2 3" but it shows "4 221 221 221 221" O_O. Any hints what i'm doing wrong?

我期待它print会显示“4 0 1 2 3”,但它会显示“4 221 221 221 221”O_O。任何提示我做错了什么?

采纳答案by Mark Tolonen

Post actual code. The C/C++ code doesn't compile as either C or C++. The Python code has syntax errors (] ending function call Foo). The code below works. The main issue after fixing syntax and compiler errors was declaring the function __stdcallso windllcould be used in the Python code. The other option is to use __cdecl(normally the default) and use cdllinstead of windllin the Python code.

发布实际代码。C/C++ 代码不会编译为 C 或 C++。Python 代码有语法错误 (] 结束函数调用 Foo)。下面的代码有效。修复语法和编译器错误后的主要问题是声明函数,__stdcall以便windll可以在 Python 代码中使用。另一个选项是在 Python 代码中使用__cdecl(通常是默认值)和使用cdll代替windll

mydll.c (cl /W4 /LD mydll.c)

mydll.c (cl /W4 /LD mydll.c)

#include <stdlib.h>

__declspec(dllexport) void __stdcall Foo(unsigned char** ppMem, int* pSize)
{
    char i;
    *pSize = 4;
    *ppMem = malloc(*pSize);
    for(i = 0; i < *pSize; i++)
        (*ppMem)[i] = i;
}

demo.py

演示文件

from ctypes import *
Foo = windll.mydll.Foo
Foo.argtypes = [POINTER(POINTER(c_ubyte)),POINTER(c_int)]
mem = POINTER(c_ubyte)()
size = c_int(0)
Foo(byref(mem),byref(size))
print size.value,mem[0],mem[1],mem[2],mem[3]

Output

输出

4 0 1 2 3