如何将指针转换为System.IntPtr(.NET)的python cffi结构? [英] How to cast a pointer to a Python cffi struct to System.IntPtr (.NET)?

查看:387
本文介绍了如何将指针转换为System.IntPtr(.NET)的python cffi结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将System.IntPtr传递给.NET函数(带有pythonnet的Python).该指针应指向在cffi中创建的结构.

I need to pass a System.IntPtr to a .NET function (Python with pythonnet). This pointer should refer to a struct created in cffi.

我发现了:

from CLR.System import IntPtr, Int32
i = Int32(32)
p = IntPtr.op_Explicit(i)

这是我到目前为止尝试过的

This is what I tried so far

import clr
from cffi import FFI

ffi = FFI()

custom_t = '''
            typedef struct
            {
                float x;
                 float y;
                 float z;

            } float3;
            '''

ffi.cdef(custom_t)

cfloat3 = ffi.new("float3 *")
cfloat3.x = 1.0
cfloat3.y = 2.0
cfloat3.z = 3.0
print(cfloat3)

from System import IntPtr

p = IntPtr.op_Explicit(id(cfloat3)) #works, sort of...
print(p)

#I would rather see something like
p2 = IntPtr.op_Explicit(ffi.addressof(cfloat3).value)
p3 = IntPtr(ffi.cast("float3*", cfloat3))
p4 = IntPtr(ffi.cast("void3*", cfloat3))

#type(_), ffi.typeof(_), ffi.typeof(_).kind, ffi.addressof()

但是我不确定是否使用

But I am not sure if using IntPtr.op_Explicit is the best solution. It looks a bit like workaround in combination with id() and I am pretty sure there is a better solution.

推荐答案

解决方案是使用IntPtr

from System import IntPtr, Int32, Int64
my_ptr = ffi.cast("intptr_t", my_c_struct)
cs_handle = IntPtr.Overloads[Int64](Int64(int(my_ptr)))

此处这是一个有效的示例:

import clr
from cffi import FFI

ffi = FFI()

custom_t = '''
            typedef struct
            {
                float x;
                 float y;
                 float z;

            } float3;
            '''

ffi.cdef(custom_t)

cfloat3 = ffi.new("float3 *")
cfloat3.x = 1.0
cfloat3.y = 2.0
cfloat3.z = 3.0
print(cfloat3)

from System import IntPtr, Int32, Int64

my_ptr = ffi.cast("intptr_t", cfloat3)
print(my_ptr)
print(ffi.typeof(my_ptr))
print(ffi.typeof(my_ptr).kind)
print(ffi.typeof(my_ptr).cname)
print(int(my_ptr))
print('hex', hex(int(my_ptr)))

#you don't need to cast to System.Int64 first, also works without:

#with casting the Python int to System.Int64
cs_handle = IntPtr.Overloads[Int64](int(my_ptr))
print(cs_handle)

#without casting the Python int to System.Int64
cs_handle = IntPtr.Overloads[Int64](Int64(int(my_ptr)))
print(cs_handle)

# using this workaround mentioned in the question also works
p = IntPtr.op_Explicit(int(my_ptr)) #works, sort of...
print('op_Explicit', p)

#careful: do not use the id() of the C structure, it is different and incorrect
print(cfloat3)
print(ffi.addressof(cfloat3[0]))
print('id(cfloat3)', id(cfloat3), hex(id(cfloat3)))

有关上面发生的事情的更多信息(在这里和那里):

Some further info on what is happening above (found here and there):

  • C#的IntPtr完全映射到C/C ++的intptr_t.

  • C#'s IntPtr maps exactly to C/C++'s intptr_t.

intptr_t能够容纳指针的整数类型

intptr_t integer type capable of holding a pointer

要强制转换为int的指针,请将其强制转换为intptr_t或uintptr_t,它们由C定义为足够大的整数类型. cffi文档和示例

To cast a pointer to an int, cast it to intptr_t or uintptr_t, which are defined by C to be large enough integer types. cffi doc with examples

IntPtr只是void *的.NET类型.

IntPtr is just a .NET type for void*.

IntPtr是C#语言中非托管指针的等效项.您可以通过强制转换来回自由转换指针.没有指针类型是 即使它的名称听起来像是指向int的指针",也与其相关联, 它等效于C/C ++中的void *.

The equivalent of an unmanaged pointer in the C# language is IntPtr. You can freely convert a pointer back and forth with a cast. No pointer type is associated with it even though its name sounds like "pointer to int", it is the equivalent of void* in C/C++.

IntPtr(5)抱怨int/long' value cannot be converted to System.IntPtr.似乎它正在尝试进行强制转换或某种形式,而不是调用构造函数. (在此处找到)

IntPtr(5) complains that int/long' value cannot be converted to System.IntPtr. It seems like it is trying to cast or something instead of calling the constructor. (found here)

CLR对象的方法有一个'_ overloads _',将很快弃用该方法,而推荐使用iPy兼容的Overloads属性. (在此处找到)

Methods of CLR objects have an '_ overloads _', which will soon be deprecated in favor of iPy compatible Overloads, attribute that can be used for this purpose. (found here)

这篇关于如何将指针转换为System.IntPtr(.NET)的python cffi结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆