my_exam.f90
module example
use iso_c_binding
implicit none
contains
subroutine my_exam(m,n,val) BIND(C,name='my_exam')
!DEC$ ATTRIBUTES DLLEXPORT :: my_exam
integer,intent(in) :: m,n
real(8),dimension(m,n),intent(inout) :: val
integer :: i,j
open(1,file = 'fortran_output.dat')
write(1,'(a)') 'input arrary'
write(1,100) ((val(i,j),j=1,n),i = 1,m)
do i = 1,m
do j = 1,n
val(i,j) = val(i,j) * (i+j)
end do
end do
write(1,'(a)') 'output arrary'
write(1,100) ((val(i,j),j=1,n),i = 1,m)
close(1)
100 format(<n>F10.3)
end subroutine
end module
ifort生成DLL
打开命令行形式的intel 64 visual studio 2012 mode
>ifort /dll my_exam.f90
my_exam.py
import ctypes as ct
import numpy as np
#导入dll
flib = ct.CDLL('my_exam.dll')
#创建矩阵
m = 10
n = 5
rng = np.random.RandomState()
val = rng.random_sample(size=(m, n)) * 10
f = open('expample_output.dat','w')
f.write('input array\n')
for line in val:
for ele in line:
f.write("{0:10.3f}".format(ele))
f.write( '\n')
# 方式1:
# m_p = ct.pointer(ct.c_int(m))
# n_p = ct.pointer(ct.c_int(n))
# val = np.asfortranarray(val).T #若不转置将面临fortran和C数组在内存中储存顺序不同的问题
# result = flib.my_exam(m_p, n_p, np.ctypeslib.as_ctypes(val))
# val = val.T
# print(val)
# 方式2:
def numpy_pointer(array):
return array.ctypes.data_as(ct.POINTER(ct.c_double))
def my_exam(m, n, val):
return flib.my_exam(ct.byref(ct.c_int(m)), ct.byref(ct.c_int(n)), numpy_pointer(val))
val = np.asfortranarray(val) #按照Fortran方式储存(fortran列主序,C行主序)
result = my_exam(m, n, val)
f.write('output array\n')
for line in val:
for ele in line:
f.write("{0:10.3f}".format(ele))
f.write( '\n')
f.close()
···