Я пытался найти собственные векторы матрицы, объявляя функции ARPACK в C++ с использованием Экстерн «C»:Адрес не прошло правильно вызова Fortran функции
extern "C" {void znaupd_(int *IDO, char *BMAT, int *N, char *WHICH,
int *NEV, double *TOL, complex<double> *RESID,
int *NCV, complex<double> *V, int *LDV,
int *IPARAM, int *IPNTR, complex<double> *WORKD,
complex<double> *WORKL, int *LWORKL,
double *RWORK, int *INFO);}
extern "C" {void zneupd_(bool *RVEC, char *HOWMNY, bool *SELECT,
complex<double> *D, complex<double> *Z,
int *LDZ, complex<double> *WORKEV,
complex<double> *SIGMA, char *BMAT, int *N,
char *WHICH, int *NEV, double *TOL,
complex<double> *RESID, int *NCV,
complex<double> *V, int *LDV, int *IPARAM,
int *IPNTR, complex<double> *WORKD,
complex<double> *WORKL, int *LWORKL, int *INFO);}
Тогда в теле моего кода, Я вызываю функции:
do{
znaupd_(&IDO, &BMAT, &N, WHICH, &NEV, &TOL, RESID, &NCV, V, &LDV, IPARAM,
IPNTR, WORKD, WORKL, &LWORKL, RWORK, &INFO);
switch(abs(IDO)){
case - 1:
for(i = 0; i < N; i++) X[i] = WORKD[IPNTR[1] + i];
gmm::mult(SM, X, Y);
for(i = 0; i < N; i++) WORKD[IPNTR[2] + i] = Y[i];
break;
case 1:
for(i = 0; i < N; i++) X[i] = WORKD[IPNTR[1] + i];
gmm::mult(SM, X, Y);
for(i = 0; i < N; i++)
{WORKD[IPNTR[2] + i] = Y[i];
WORKD[IPNTR[3] + i] = X[i];}
break;
case 2:
for(i = 0; i < N; i++)
WORKD[IPNTR[2] + i] = WORKD[IPNTR[1] + i];
break;
}
}while(IDO != 99);
std::cout << &INFO << std::endl;
zneupd_(&RVEC, &HOWMNY, SELECT, D, Z, &LDZ, WORKEV, &SIGMA, &BMAT, &N,
WHICH, &NEV, &TOL, RESID, &NCV, V, &LDV, IPARAM, IPNTR, WORKD,
WORKL, &LWORKL, &INFO);
После компиляции и выполнения программы segfaults. Выполнение backtrace с GDB показывает, что адрес, передаваемый zneupd_ на & INFO, равен 0x0, что вызывает segfault, когда zneupd_ пытается присвоить новое значение этой позиции. Когда я перехожу к следующему кадру и использую печать & INFO, мне сообщили, что INFO хранится в регистре 0x28a27c. По какой-то причине моя программа не передает правильное расположение INFO в zneupd_. Что еще более озадачивает, так это то, что znaupd_ может правильно получать & INFO и может без проблем получать и изменять значение в этом месте. Может ли кто-нибудь сказать мне, почему одна функция может получить аргумент правильно, а другая не может?
Для некоторого компилятора вы должны указать экспортированную сигнатуру функции. (http://www.yolinux.com/TUTORIALS/LinuxTutorialMixingFortranAndC.html) – Mario
Красивые отступы и стиль подставки! – user1233963
@ user1233963, большой палец вверх для иронии :-) –