python - 使用 CFFI 在 Fortran 中使用 Python 函数。cffi 构建中的警告。我无法在控制台或文件中打印结果,但运行时没有错误
问题描述
编码
我遵循“CFFI 文档版本 1.15.0”部分“9.1 用法”中描述的文档,但使用“身份”功能进行了简化。
第 1 步 - plugin.h
# ifndef CFFI_DLLEXPORT
# if defined(_MSC_VER)
# define CFFI_DLLEXPORT extern __declspec(dllimport)
# else
# define CFFI_DLLEXPORT extern
# endif
#endif
CFFI_DLLEXPORT int identity(int);
第 2 步 - plugin_build.py
import cffi
ffiBuilder = cffi.FFI()
with open('plugin.h') as f:
data = ''.join([line for line in f if not line.startswith('#')])
data = data.replace('CFFI_DLLEXPORT', '')
ffiBuilder.embedding_api(data)
ffiBuilder.set_source("my_plugin", r'''
#include "plugin.h"
''')
# Here thanks to @Armin in the comment I replace 'value'
# inside print and fw.write with 'str(value)' to avoid "python crash"
ffiBuilder.embedding_init_code("""
from my_plugin import ffi
@ffi.def_extern()
def identity(value):
print(str(value))
with open('results.txt', 'w') as fw:
fw.write(str(value))
return value
""")
ffiBuilder.compile(target="plugin-1.5.*", verbose=True)
第 4 步 - 执行 plugin_build.py
python plugin_build.py 我在控制台收到了
generating .\my_plugin.c
the current directory is 'C:\\Users\\utente\\...\\FortranFiles\\CFFIexample5'
running build_ext
building 'my_plugin' extension
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\include -IC:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\include -IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\ATLMFC\include -IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include -IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um -IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt -IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\shared -IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\um -IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\winrt -IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\cppwinrt /Tcmy_plugin.c /Fo.\Release\my_plugin.obj
my_plugin.c
my_plugin.c(1060): warning C4047: 'function': 'volatile PVOID *' differs in levels of indirection from 'volatile int *'
my_plugin.c(1060): warning C4022: '_InterlockedCompareExchangePointer': pointer mismatch for actual parameter 1
my_plugin.c(1060): warning C4022: '_InterlockedCompareExchangePointer': pointer mismatch for actual parameter 2
my_plugin.c(1060): warning C4022: '_InterlockedCompareExchangePointer': pointer mismatch for actual parameter 3
my_plugin.c(1060): warning C4047: '==': 'PVOID' differs in levels of indirection from 'int'
my_plugin.c(1095): warning C4047: 'function': 'volatile PVOID *' differs in levels of indirection from 'volatile int *'
my_plugin.c(1095): warning C4022: '_InterlockedCompareExchangePointer': pointer mismatch for actual parameter 1
my_plugin.c(1095): warning C4022: '_InterlockedCompareExchangePointer': pointer mismatch for actual parameter 2
my_plugin.c(1095): warning C4022: '_InterlockedCompareExchangePointer': pointer mismatch for actual parameter 3
my_plugin.c(1095): warning C4047: '==': 'PVOID' differs in levels of indirection from 'int'
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\libs /LIBPATH:C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\PCbuild\amd64 /LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\ATLMFC\lib\x64 /LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\lib\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\ucrt\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x64 python39.lib /EXPORT:PyInit_my_plugin .\Release\my_plugin.obj /OUT:.\plugin-1.5.dll /IMPLIB:.\Release\plugin-1.5.lib /MANIFEST
Library creation .\Release\plugin-1.5.lib e dell'oggetto .\Release\plugin-1.5.exp
Code generation in progress ...
Code generation finished
此命令在根项目文件夹中创建 my_plugin.c、plugin-1.5.dll 并在根项目文件夹内的 Release 文件夹中创建 my_plugin.obj、plugin-1.5.exp 和 plugin-1.5.lib。
第 5 步 - 创建 Fortran esempio.f90
program esempio
use, intrinsic :: iso_c_binding, only : c_int
integer(c_int) :: intero
interface
subroutine identity(a, output) bind (c, name="identity")
use iso_c_binding
integer(c_int), intent(in) :: a
integer(c_int), intent(out) :: output
end subroutine identity
end interface
call identity(4, intero)
open(unit=100, file='filename.txt', status="unknown", action="write")
write(100, '(I0)') intero
end program esempio
第 6 步 - 链接所有内容
gfortran -o testtest.exe esempio.f90 -L. plugin-1.5.dll
命令执行时没有在控制台打印任何消息,生成了可执行文件 testtest.exe。
第 7 步 - 运行可执行文件
在运行 testtest.exe 之前,我设置了 PYTHONHOME 环境。执行的命令没有在控制台中打印任何消息,并且创建了任何文件。为什么?我希望文件和打印在控制台中,但没有任何反应。
技术背景
- 操作系统视窗 10
- Python Anaconda3,Python 3.9.7
- gFortran GNU Fortran(x86_64-posix-seh-rev0,由 MinGW-W64 项目构建)8.1.0
帮助 请告诉我一些事情要继续,因为我在第 4 步中看到了“警告”,我不知道它们是否可以忽略不计以及如何继续纠正它们。谢谢你。
解决方案
我设法让您的代码在 Linux 上运行。我不能保证它会在 Windows 上正常工作,但这些更改是有意义的,至少应该让你非常接近。
当你在 C 中有一个非 void 函数时,使用一个函数,而不是子例程
value
使用属性传递参数
integer(c_int) :: intero
interface
function identity(a) result(output) bind (c, name="identity")
use iso_c_binding
integer(c_int), value :: a
integer(c_int) :: output
end function identity
end interface
intero = identity(4_c_int)
免责声明:我从未使用过 CFFI,也没有研究过它的任何文档,我只是应用了看起来足够明显的更改。
推荐阅读
- powerbi - 累计值已知时的每日值 Power BI
- azure-machine-learning-service - 使用环境对象的 AML 服务评分
- r - R Shiny:将文本输出框固定到屏幕底部
- python - 将熊猫数据框转换为 JSON 对象列
- reactjs - ReactJS,一个组件正在更改要控制的类型编号的不受控制的输入
- php - 在 PHP 中转换一个 3 维数组
- mysql - 在逗号内加入单个值的字符串
- amazon-web-services - terraform plan:错误:尝试创建 cloudwatch 事件目标时 sqs_target 应该是一个列表
- python - 定期使用 python 使窗口聚焦
- excel - 过滤表格列表以仅包含有用的行