【问题标题】:Fortran DLL in Python wrapper, output for same function variesPython 包装器中的 Fortran DLL,相同函数的输出不同
【发布时间】:2017-03-09 03:24:01
【问题描述】:

我已经从这个question修改了我的代码

我的最终目标是: - 在 DLL 中打包一些 Fortran 代码(已经完成) - 创建一个 Python 包装器作为从源接收输入的接口,并将这些输入提供给 DLL 并将它们传递给 DLLs Fortran 函数 - 返回函数的输出以传递给另一个 Python 程序。

到目前为止,我一直在使用这个示例作为原型(我最终会对此进行调整),每次都会得到不同的输出。

如图所示:

    C:\Users\NAME\Desktop>python.exe py_wrapper.py
    <CDLL 'fort_test', handle 6f800000 at 0x25e174ec2e8>
    <_FuncPtr object at 0x0000025E17617388>
    <_FuncPtr object at 0x0000025E17617388>
    c_long(3)
    390943376        <---int value (my annotation for clarity)
    <class 'int'>
    c_long(390943376)
    <__main__.LP_c_long object at 0x0000025E174D54C8>

    C:\Users\NAME\Desktop>python.exe py_wrapper.py
    <CDLL 'fort_test', handle 6f800000 at 0x23fa636c2e8>
    <_FuncPtr object at 0x0000023FA6497388>
    <_FuncPtr object at 0x0000023FA6497388>
    c_long(3)
    -1506454896       <---int value (my annotation for clarity)
    <class 'int'>
    c_long(-1506454896)
    <__main__.LP_c_long object at 0x0000023FA63554C8>

这是我的 Fortran 代码的内容:

    subroutine ex(i)
    integer i
    i=i+1
    return i
    end     

这是我的 Python 包装器:(这里有很多测试内容)

    from ctypes import *

    DLL = CDLL('fort_test')
    print(DLL)

    print(getattr(DLL, 'ex_'))
    print(DLL.ex_)

    x = pointer(c_int(3))
    print(x.contents)
    res = DLL.ex_(x)
    print(res)
    print(type(res))
    proc_res = pointer(c_int(res))
    print(proc_res.contents)
    print(proc_res)

我的问题是,有谁知道为什么这个输出不断变化?我在代码中的输入是 3,给定函数我希望输出为 4,但我得到的是内存地址(请参阅输出示例中的注释)或内存地址的有符号整数表示?

【问题讨论】:

  • 虽然这里没关系,但Fortran子程序中的return i可能并不像你想的那样。
  • 哦,我忘了把它拿出来哈。我在摆弄东西,我真的不太了解fortran哈哈(因此我为什么要包装它,我真正想做的代码要大得多,我不能在这里发布)跨度>
  • 我不熟悉 Fortan 调用约定,但您正在传递一个指向整数而不是实际整数的指针。我的猜测是您收到的是地址而不是价值。你试过简单的res = DLL.ex_(3)吗?
  • @MarkTolonen 我试过这个,它返回:WindowsError:异常:访问冲突读取 0x0000000000000003,所以它需要一个地址,但它没有返回一个值。

标签: python dll fortran ctypes


【解决方案1】:

更新:

我的问题已经解决了。

from ctypes import *

DLL = windll.fort_test
print DLL

x = byref(c_int(3)) 
print x res = DLL.ex_( x )
print cast(res,POINTER(c_int)).contents

我也清理了很多。 我仍然通过引用传递,然后将返回的内存地址转换为 c_int 指针(所有大写都很重要)并使用'.contents'函数指针取消引用它

【讨论】:

  • 查找argtypesrestype 让通话更轻松。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
  • 2012-06-24
  • 2018-10-12
  • 2021-07-09
  • 2021-07-21
  • 1970-01-01
相关资源
最近更新 更多