Сбой при вызове библиотеки C ++ из Perl с использованием SWIG (AIX 5.1) - PullRequest
4 голосов
/ 09 октября 2008

Я пытаюсь вызвать библиотеку C ++ из Perl на машине с AIX 5.1. Я создал очень простой тестовый проект, чтобы попробовать это.

Моя общая библиотека C ++ (test.cpp):

#include <stdio.h>
#include <iostream>

void myfunc()
{
    printf("in myfunc()\n");
    std::cout << "in myfunc() also" << std::endl;
}

Мой файл интерфейса SWIG (test.i):

%module test
%{
void myfunc();
%}
void myfunc();

Затем я создаю общий объект следующим образом:

swig -c++ -perl test.i
g++ -c test_wrap.cxx -I/usr/opt/perl5/lib/5.6.0/aix/CORE -o test_wrap.o
g++ -c test.cpp -o test.o
ld -G -bI:/usr/opt/perl5/lib/5.6.0/aix/CORE/perl.exp -bnoentry -bexpall -lc_r test.o test_wrap.o -o test.so

На данный момент у меня есть общий объект test.so, который должен быть загружен в perl (через сгенерированный SWIG test.pm). У меня есть очень простой Perl-скрипт, чтобы попытаться загрузить общий объект и вызвать функцию, которую я экспортирую (test.pl):

#!/usr/bin/perl
use test;
test::myfunc();

Когда я запускаю test.pl, я получаю следующий вывод:

в myfunc ()
Недопустимая инструкция (ядро сброшено)

Если я закомментирую использование std::cout в myfunc, оно работает без проблем. Кажется, что использование чего-либо в C ++ STL вызывает дамп ядра (я пытался просто объявить std::vector и std::stringstream, оба результата приводят к дампу ядра). Я могу создать автономный исполняемый файл C ++, который использует STL без проблем, только когда он вызывается в моем общем объекте при загрузке из perl, я попадаю в проблему.

Я также пытался использовать xlc вместо gcc, но получаю тот же результат. Я думаю, что есть какой-то прикольный флаг компоновщика, который мне нужно передать, чтобы убедиться, что вся связь происходит правильно? Любые идеи приветствуются ...

Редактировать: Если я создаю ссылку, используя gcc / xlc вместо прямого вызова компоновщика (ld), я немедленно получаю ошибку сегментации. Похоже, что происходит сбой, когда Perl пытается просто загрузить общую библиотеку. Вызов ld, как я описал выше, наиболее близок к тому, чтобы он работал, но я думаю, что мне не хватает некоторых библиотек или специальных флагов компоновщика AIX для библиотек C ++.

Edit2: Хорошо, у меня это работает. AIX очень хрупкая, когда дело доходит до ссылок. В итоге я пришел к следующей команде link, которая, кажется, работает правильно:

ld -G -bI:/usr/opt/perl5/lib/5.6.0/aix/CORE/perl.exp -bnoentry -bexpall -lC -lc -ldl test.o test_wrap.o -o test.so

Библиотеки, с которыми я связан, являются наиболее актуальными. Оказывается, порядок, в котором упоминаются библиотеки, также очень важен (тьфу). Также обратите внимание, что это делается на Perl 5.6.0, который поставляется с AIX 5.1. Я пытался создать это же простое приложение для Perl 5.8.8, и оно не работает. Тем не менее, я уверен, что гораздо более вменяемый метод связывания (использующий прямой gcc / xlc вместо прямого вызова ld), кажется, работает лучше. Таким образом, эта проблема является ошибкой в ​​дистрибутиве Perl или компоновщике или что-то в этом роде.

Надеюсь, это поможет проклятому душевнобольному человеку работать с AIX ...

Ответы [ 2 ]

4 голосов
/ 09 октября 2008

Не могли бы вы просто добавить свой libstdc ++ в команду ld? например, -lstdc++?

То, что я сделал в Linux, после репликации вашей проблемы было:

gcc -g -lstdc++ -shared test*.o -o test.so

Тогда проблема ушла.

(Попытка получить правильный список библиотек для ld была слишком большой работой, поэтому я просто сказал gcc сделать это для меня.)

0 голосов
/ 09 октября 2008

Я ничего не знаю о SWIG, но вы также можете проверить, что он ожидает функцию с использованием cdecl (а не pascal, fastcall или какого-либо другого соглашения о вызовах). Использование неправильного между инструментами может привести к «плохим вещам» (насколько я могу судить, обычно это повреждение стека).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...