将 C 对象 (CFFI) 传递给 .NET (Pythonnet)
Passing C objects (CFFI) to .NET (Pythonnet)
使用 Python,我想使用在 dll 中定义的 C 或 C++ 结构并将它们传递给用 C# 编写的 .NET dll。 C或C++ dll使用cffi添加,.NET使用pythonnet加载。
结构的定义在两个 dll 中是相同的。
这里是一个float2的简单例子,当然现实要复杂得多:)
import sys
import clr
import numpy as np
sys.path.append('my_dot_net.dll')
#load the .NET dll
clr.AddReference("dot_net_dll")
from cffi import FFI
ffi = FFI()
#load C dll
lib = ffi.dlopen('c.dll')
# definition of a simple struct, there is an identical one in .NET
ffi.cdef('''typedef struct
{
float x;
float y;
} float2;''')
from dot_net_namespace import float2
#float2 type in dot net
dotnet_float2 = float2()
dotnet_float2.x = 1.0
dotnet_float2.y = 2.0
#float2 in the c dll
c_float2 = ffi.new("float2 *") # usually numpy array
c_float2.x = 1.0
c_float2.y = 2.0
现在我想,例如创建 .NET 数据类型的数组或将对象分配给 .NET 中可用的结构并将 C 类型对象分配给该结构:
dot_net_float2_array = System.Array.CreateInstance(dot_net_float2, 100)
dot_net_float2_array[0] = c_float2 #does not work
dot_net_struct.xy = c_float2 #does not work
我收到不同的错误消息,例如
TypeError: Cannot convert <cdata 'float2[]' owning 8240 bytes> to dot_net_namespace.float2[]
'_cffi_backend.CDataOwn' value cannot be converted to dot_net_namespace.float2
TypeError: initializer for ctype 'float2' must be a list or tuple or dict or struct-cdata, not float2
我不知道如何解决这个问题。我正在处理的真实代码应该使用包含结构数组的结构,我什至无法将这个简单的示例添加到 运行 :)
当然可以逐字段复制struct,但是有没有更方便的方法呢?这可能吗?
是否可以使用 ffi.cast
或 ffi.buffer
?
我最终传递了指向 .NET 的指针。它们可以按照我在这里的其他问题中的描述进行铸造。一旦我的编辑被审查并被接受,完整的答案就会出现。
此后 Marshal.PtrToStructure Method (IntPtr, Type) 用于在 .NET 中重新组装结构。
使用 Python,我想使用在 dll 中定义的 C 或 C++ 结构并将它们传递给用 C# 编写的 .NET dll。 C或C++ dll使用cffi添加,.NET使用pythonnet加载。
结构的定义在两个 dll 中是相同的。
这里是一个float2的简单例子,当然现实要复杂得多:)
import sys
import clr
import numpy as np
sys.path.append('my_dot_net.dll')
#load the .NET dll
clr.AddReference("dot_net_dll")
from cffi import FFI
ffi = FFI()
#load C dll
lib = ffi.dlopen('c.dll')
# definition of a simple struct, there is an identical one in .NET
ffi.cdef('''typedef struct
{
float x;
float y;
} float2;''')
from dot_net_namespace import float2
#float2 type in dot net
dotnet_float2 = float2()
dotnet_float2.x = 1.0
dotnet_float2.y = 2.0
#float2 in the c dll
c_float2 = ffi.new("float2 *") # usually numpy array
c_float2.x = 1.0
c_float2.y = 2.0
现在我想,例如创建 .NET 数据类型的数组或将对象分配给 .NET 中可用的结构并将 C 类型对象分配给该结构:
dot_net_float2_array = System.Array.CreateInstance(dot_net_float2, 100)
dot_net_float2_array[0] = c_float2 #does not work
dot_net_struct.xy = c_float2 #does not work
我收到不同的错误消息,例如
TypeError: Cannot convert <cdata 'float2[]' owning 8240 bytes> to dot_net_namespace.float2[]
'_cffi_backend.CDataOwn' value cannot be converted to dot_net_namespace.float2
TypeError: initializer for ctype 'float2' must be a list or tuple or dict or struct-cdata, not float2
我不知道如何解决这个问题。我正在处理的真实代码应该使用包含结构数组的结构,我什至无法将这个简单的示例添加到 运行 :)
当然可以逐字段复制struct,但是有没有更方便的方法呢?这可能吗?
是否可以使用 ffi.cast
或 ffi.buffer
?
我最终传递了指向 .NET 的指针。它们可以按照我在这里的其他问题中的描述进行铸造。一旦我的编辑被审查并被接受,完整的答案就会出现。
此后 Marshal.PtrToStructure Method (IntPtr, Type) 用于在 .NET 中重新组装结构。