Я могу обернуть функцию C с f2py
следующее:
foo.c
#include <stdio.h>
void func(int n, int * a) {
printf("%d\n", n);
}
Соответствующий файл интерфейса
foo.pyf
python module foo
interface
subroutine func(n, a)
intent(c) func
intent(c)
integer, intent(hide) :: n = shape(a,0)
real(kind=8), dimension(n), intent(in) :: a
end subroutine func
end interface
end python module foo
Затем я выполняю, f2py foo.pyf -c foo.c -m foo
, который создает библиотеку Python, и так, например, код
import numpy as np
import foo
foo.func( np.ones(3) )
печать 3
как и следовало ожидать.
foo.c
→ foo.cpp
приводит к неопределенному символуИзменяя расширение foo.c
в foo.cpp
Я заметил, что
f2py foo.pyf -c foo.cpp -m foo
звонки g++
вместо gcc
, Хорошо. Однако потом, когда я выполню, import foo
в Python я вижу:
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: ./foo.so: undefined symbol: func_
Какую магию я должен применить, чтобы сделать f2py
работать с кодом C ++? Является ли это возможным?
Дополнительное примечание:
Если я уберу строку intent(c) foo
в файле интерфейса, затем foo.c
приводит к тому же поведению, то есть компилируется с f2py
выдает ту же неопределенную ошибку символа при импорте из Python.
Ах, это почти наверняка проблема с искажением имени.
Имена C ++ хранятся в компоновщике с гораздо более сложными «искаженными» именами, чем их аналоги «C», чтобы различать перегруженные имена, которые C ++ допускает даже для функций, не относящихся к классу.
Вы можете объявить функцию как extern "C"
так что он экспортируется с использованием соглашения по именованию C. Тело функции может по-прежнему использовать функции c ++, но затем оно должно быть видимым для f2py или аналогичного.
Обратите внимание, что это мешает вам использовать перегрузку имени C ++ для этого имени функции.
Других решений пока нет …