Я обернул подпрограммы sqlite3_open, sqlite3_close и sqlite3_exec из C-API SQLite (версия 3.16.2), чтобы вызывать их из программа на Фортране 2003, использующая модуль ISO_C_BINDING. Я использую компилятор Intel Fortran 17 (ifort) с MSVC 14 в Windows и с gcc в Linux.
Моя цель — открыть базу данных SQLite и сохранить указатель на дескриптор соединения с базой данных, чтобы я мог использовать его для хранения/извлечения результатов, когда программа Fortran выполняет цикл своих вычислений. Псевдокод основной программы будет выглядеть примерно так:
program main
use, intrinsic :: iso_c_binding
use sqlite_wrapper_module
implicit none
! QUESTION: SHOULD DB_HANDLE BE TYPE(C_PTR) OR A STRUCT OF SOME KIND?
type(C_PTR) :: db_handle
character(len=:), allocatable :: db_name
db_name = "test.db"//C_NULL_CHAR
call sqlite3_open_WRAPPER(db_name, db_handle) ! wraps sqlite3_open
do i=1,n
...compute stuff...
call sqlite3_exec_WRAPPER(db_handle, sql_stmt) ! wraps sqlite3_exec
...compute stuff...
enddo
call sqlite3_close_WRAPPER(db_handle) ! wraps sqlite3_close
end program main
Я определил явные интерфейсы к подпрограммам-оболочкам C в отдельном модуле. Например:
module sqlite_wrapper_module
use, intrisic :: iso_c_binding
implicit none
interface
subroutine sqlite3_open_WRAPPER(db_name, db_handle) bind(C)
import
character(kind=C_CHAR), dimension(*) :: db_name
type(C_PTR), value :: db_handle
end subroutine sqlite3_open_wrapper
end interface
end module sqlite_wrapper_module
Я не уверен, что понимаю официальную документацию, но они, похоже, утверждают, что *db указатель, представляющий дескриптор соединения с базой данных, который представляет собой «непрозрачную структуру», определенную как typedef struct sqlite3 sqlite3;
. Я точно не знаю, что это значит (программирование на C не моя сильная сторона). Поэтому я попытался установить C_PTR из Fortran следующим образом:
int sqlite3_open_WRAPPER(char *filename, sqlite3 *pdb) {
sqlite3 *db;
int rc=sqlite3_open(filename, &db);
pdb=db; // <---------------------------------This
...check rc...
return 0;
}
Сначала кажется, что это работает. Однако указатель возвращается к NULL после передачи обратно в программу на Фортране и не может использоваться в sqlite3_exec или sqlite3_close. Должен ли я определить какую-то struct
в программе на Фортране, чтобы она действовала как структура соединения с базой данных, и передать ее в подпрограммы C?