[英]undefined reference to 'SolveBIE_' when binding C++ and Fortran
[英]Binding C++ and Fortran
我想將C ++和Fortran結合在一起。 我的Fortran代碼將使用C ++函數,而C ++函數將更改Fortran的變量並將其發送回去。 C ++函數是用其他C ++代碼構建的,例如C ++函數將使用其他.cpp文件中的某些子函數。 我使用ifort
制作了Fortran代碼,並將C ++函數作為一個目標文件test.o添加到了我的Fortran生成文件中。 我還將每個需要的C ++ .o文件(支持test.o)放在makefile中。 顯示錯誤
#6633,“實際參數的類型與虛擬參數的類型不同”。
這是代碼。
Fortran代碼
use, intrinsic :: ISO_C_BINDING, only: C_INT, C_DOUBLE
implicit double precision(a-h,o-z),integer(i-n)
Interface
integer (C_INT) function SolveBIE_(x, y, aa, m) BIND(C, NAME='SolveBIE_')
use, intrinsic :: ISO_C_BINDING
implicit none
type (C_PTR), value :: x
type (C_PTR), value :: y
type (C_PTR), value :: aa
integer (C_INT), value :: m
end function SolveBIE_
end Interface
integer (C_INT) :: m
real (C_DOUBLE), ALLOCATABLE, DIMENSION(:,:), target :: x
real (C_DOUBLE), ALLOCATABLE, DIMENSION(:,:), target :: y
real (C_DOUBLE), ALLOCATABLE, DIMENSION(:,:), target :: aa
ALLOCATE(x(0:MAXLEN,MAXINTERFACES))
ALLOCATE(y(0:MAXLEN,MAXINTERFACES))
ALLOCATE(aa(0:MAXLEN,MAXINTERFACES))
我的Fortran代碼運行
mm = SolveBIE_(x(1,1),y(1,1),aa(1,1),m)
使用C ++代碼以及錯誤的出處是在x, y, aa
我使用x(1,1)
而不是x
,因為如果使用x
,那么還會有另一個錯誤
#6634,“違反了實際參數和虛擬參數的形狀匹配規則”
我不明白為什么它應該是x(1,1)
。 為什么這樣做有效,而不是x
?
我的C ++代碼
#ifdef __cplusplus
extern "C" {
#endif
int solveBIE_(double *ini_bdry_x, double *ini_bdry_y, double *ini_bdry_um, int *fM)
{
double(*bdry_node)[2] = new double[M1][2];
for (int k = 0; k < M; k++) {
bdry_node[k+1][0] = ini_bdry_x[k+1];
bdry_node[k+1][1] = ini_bdry_y[k+1];
bdry_theta[k+1] = Atan(ini_bdry_x[k+1], ini_bdry_y[k+1]);}
... some functions in other .cpp file
編寫接口的方式,您必須構造一個C_PTR
來數組x
並將其作為第一個參數傳遞:
use, intrinsic :: ISO_C_BINDING, only: C_INT, C_DOUBLE, C_PTR, C_LOC
! ...
type(C_PTR) PTRx
! ...
PTRx = C_LOC(x(LBOUND(x,1),LBOUND(x,2)))
! ...
mm = solveBIE_(PTRx, PTRy, PTRaa, m)
如上所示,您還必須修復接下來的兩個參數。 但是您需要重寫參數fM
的接口,因為就目前情況而言,Fortran將按值傳遞整數,而C ++則期望使用指針。 鑒於此,我將使用在C ++函數中為參數指定的名稱並通過引用傳遞所有內容來完全重寫接口。 偽參數的名稱可能在Fortran中可見,因此使它們有意義是很有用的。 在下文中,我假設fM
指向被調用者中的標量:
Interface
function SolveBIE_(ini_bdry_x, ini_bdry_y, ini_bdry_um, fM) &
BIND(C, NAME='SolveBIE_')
import
implicit none
integer(C_INT) SolveBIE_
real(C_DOUBLE) :: ini_bdry_x(*)
real(C_DOUBLE) :: ini_bdry_y(*)
real(C_DOUBLE) :: ini_bdry_um(*)
integer (C_INT) :: fM
end function SolveBIE_
end Interface
然后,您以后可以正常地或多或少地調用它
mm = SolveBIE_(x,y,aa,m)
注意x(1,1)
是錯誤的,因為LBOUND(x,1) = 0
,而不是1
!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.