2015-09-03 5 views
2

Под Mac OS X с g ++ из gcc-5.2 Я пытаюсь сделать следующее: создать dylib, экспортирующий класс, определенный заголовком tmp8bis_dylib.h, и источник tmp8bis_dylib.cpp, а затем создать другой dylib из исходного файла tmp8bis.cpp с использованием и ссылкой на предыдущий dylib. Заголовок и источники находятся в одном каталоге. Я скомпилировать следующим образом:динамическая библиотека dylib, вызывающая dylib: неопределенные символы для архитектуры i386

g++-5.2.0 -m32 -Wall -g -c ./tmp8bis_dylib.cpp 
g++-5.2.0 -m32 -dynamiclib ./tmp8bis_dylib.o -o ./tmp8bis_dylib.dylib 
g++-5.2.0 -m32 -Wall -g -c ./tmp8bis.cpp 
g++-5.2.0 -m32 -dynamiclib ./tmp8bis.o -o ./tmp8bis.dylib 

и получить это:

Undefined symbols for architecture i386: 
    "complex::cmodule(double, double)", referenced from: 
     _mymodule in tmp8bis.o 
    "complex::complex(double, double)", referenced from: 
     _mymodule in tmp8bis.o 
    "complex::~complex()", referenced from: 
     _mymodule in tmp8bis.o 
ld: symbol(s) not found for architecture i386 
collect2: error: ld returned 1 exit status 
make: *** [all] Error 1 

Очевидно, что я пытался передать различные включаемые и библиотечные пути с -I и -L флаги соответственно, с тем же результатом ... Любые идея?

Файлы ниже:

Для tmp8bis_dylib.h:

#ifndef TMP_8_BIS_DYLIB_H 
#define TMP_8_BIS_DYLIB_H 

class complex 
{ 
public: 
     double real; 
     double imag; 
public: 
     complex(); 
     complex(double x); 
     complex(double x,double y); 
     double cmodule(double x, double y); 
     ~complex(); 
}; 

#endif 

Для tmp8bis_dylib.cpp:

#include "./tmp8bis_dylib.h" 
#include <math.h> 

extern "C" 
{ 
     complex::complex() 
     { 
      real = 0.0 ; 
      imag = 0.0 ; 
     } 

     complex::complex(double x) 
     { 
      real = x ; 
      imag = 0.0 ; 
     } 

     complex::complex(double x,double y) 
     { 
      real = x ; 
      imag = y ; 
     } 

     double complex::cmodule(double x, double y) 
     { 
      double res = sqrt(x*x+y*y); 
      return res ; 
     } 

     complex::~complex() 
     { 

     } 
} 

Для tmp8bis.cpp:

#include <math.h> 
#include "./tmp8bis_dylib.h" 

extern "C" 
{ 
     double mymodule(double x, double y) 
     { 
      complex z(x,y); 
      double ret = z.cmodule(x,y); 
      return ret; 
     } 
} 

Точность.-m32 - это потому, что мне нужно 32 бита dylib, потому что окончательный dylib будет подключен к excel 2011 (для Mac) VBA, который составляет 32 бит.

EDIT. После Brett Hale 'комментарий s о Apple's advises about dylibs, я добавил

#define EXPORT __attribute__((visibility("default"))) 

после того, как #include-х из tmp8bis.cpp и EXPORT «S для всех своих функций членов и составлен следующим образом:

g++-5.2.0 -m32 -Wall -g -c ./tmp8bis_dylib.cpp 
g++-5.2.0 -m32 -dynamiclib ./tmp8bis_dylib.o -fvisibility=hidden -o ./tmp8bis_dylib.dylib 

сделал sudo cp ./tmp8bis_dylib.dylib /opt/lib/libtmp8bis_dylib.dylib, а затем скомпилировал:

g++-5.2.0 -m32 -Wall -g -c ./tmp8bis.cpp 
g++-5.2.0 -m32 -dynamiclib ./tmp8bis.o -o ./tmp8bis.dylib -L/opt/lib 

a nd получил тот же результат, что и раньше ... Не было

g++-5.2.0 -m32 -dynamiclib ./tmp8bis.o -o ./tmp8bis.dylib -ltmp8bis_dylib.dylib 

сделать мой день.

+0

Вы не можете обернуть методы C++ в 'extern 'C'', так как это изменяет соглашения о вызовах - или, по крайней мере, имя, управляющее символами. Почему бы просто не использовать [''] (http://en.cppreference.com/w/cpp/numeric/complex) для класса 'std :: complex '? –

+0

Я должен был уточнить, что мой «сложный» класс был просто оправданием для примера. Как я мог достичь того, чего хочу?(Кстати, я уже использовал dylibs, связываясь с ними и включая их заголовочные файлы, поэтому то, что я хочу достичь, возможно наверняка, но, условно для вашего комментария, невозможно с тем, как я пытаюсь это сделать. –

+0

OS X [ динамические библиотеки] (https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html#//apple_ref/doc/uid/TP40001908-SW1). –

ответ

0

Не прибегая к #define EXPORT __attribute__((visibility("default"))) или любой -fvisibility=hidden

g++-5.2.0 -m32 -Wall -fpic -g -c ./tmp8bis_dylib.cpp 
g++-5.2.0 -m32 -shared ./tmp8bis_dylib.o -o ./libtmp8bis_dylib.dylib 
g++-5.2.0 -m32 -Wall -g -c ./tmp8bis.cpp 
g++-5.2.0 -m32 -shared ./tmp8bis.o -o ./tmp8bis.dylib -L. -ltmp8bis_dylib 

наконец работал. Мне не удалось добиться успеха без -fpic, назвав libtmp8bis_dylib.dylib и используя -ltmp8bis_dylib.