Создание и использование общей библиотеки из исходных файлов, использующих другую общую библиотеку. (внутри)

Я новичок в создании приложений на С++ и RInside (библиотека, которая обеспечивает доступ к встроенному интерпретатору R из программы на С++), и мне нужна помощь. Я хочу, чтобы весь код, использующий RInside, был разделен в классе/модуле и предоставлял только функцию (получение некоторого ввода, выполнение некоторой задачи с использованием RInside и возврат вывода) другим программам, которым нужны эти данные. Я экспериментирую, могу ли я использовать эту функциональность в другом проекте/модуле (жилы Omnet++, если кто-то хочет конкретно), в котором так много других исходных файлов и отдельных make-файлов. если возможно, я бы не хотел касаться этих модулей и процесса их компиляции. Итак, я попробовал простой пример и сомневаюсь в построении. У меня есть код RInside в классе Test1, и я хочу использовать его в классе Test2. Насколько я понимаю, я использую RInside в качестве разделяемой библиотеки. Поэтому мне нужно создать общую библиотеку с помощью Test1 и включить ее или указать ссылку на нее в Test2.

Каталог Shared_1: Test1.h, Test1.cc: класс Test1

Каталог shared_2: Test2.h, Test2.cc: класс Test2

Test1.h -> Includes “Rinside.h”     
Test1.cc -> includes “Test1.h”  
-> main(): Create a Test1 object and call test1Function1() 
->test1Function1() : Creates an embedded R instance and does some functionality

Test2.h -> Includes “Test1.h”         
Test2.cc -> includes “Test2.h”   
-> main() : Create a Test2 object and call  test2Function1()
-> test2Function1() : Create a Test1 object and call  test1Function1()   

Я создал libTest1_1.so из Test1.cc следующим образом.

g++ -I/usr/share/R/include -I/home/aelab/R/x86_64-pc-linux-gnu-library/3.4/Rcpp/include -I/home/aelab/R/x86_64-pc-linux-gnu-library/3.4/RInside/include -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -g -Wall ./shared_1/Test1.cc  -Wl,--export-dynamic -fopenmp -Wl,-Bsymbolic-functions -Wl,-z,relro -L/usr/lib/R/lib -lR -lpcre -llzma -lbz2 -lz -lrt -ldl -lm  -lblas -llapack  -L/home/aelab/R/x86_64-pc-linux-gnu-library/3.4/RInside/lib -lRInside -Wl,-rpath,/home/aelab/R/x86_64-pc-linux-gnu-library/3.4/RInside/lib -fPIC -shared -o ./shared_1/libTest1_1.so

Я хочу использовать test1Function1() из Test1.cc в Test2.cc и, если возможно, скомпилировать Test2.cc с различными параметрами для g++. Когда я компилирую Test2.cc, используя все библиотеки (библиотеки, используемые для сборки Test1.cc, а также libTest1_1.so), все работает хорошо.

g++ -I ./shared_1/ -I/usr/share/R/include -I/home/aelab/R/x86_64-pc-linux-gnu-library/3.4/Rcpp/include -I/home/aelab/R/x86_64-pc-linux-gnu-library/3.4/RInside/include -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -g -Wall ./shared_2/Test2.cc  -Wl,--export-dynamic -fopenmp -Wl,-Bsymbolic-functions -Wl,-z,relro -L/usr/lib/R/lib -lR -lpcre -llzma -lbz2 -lz -lrt -ldl -lm  -lblas -llapack -L/home/aelab/R/x86_64-pc-linux-gnu-library/3.4/RInside/lib -lRInside -Wl,-rpath,/home/aelab/R/x86_64-pc-linux-gnu-library/3.4/RInside/lib -L./shared_1/ -lTest1_1 -fPIC -o ./shared_2/Test2.o

Но когда я скомпилирую его, просто скомпилировав его, предоставив включаемый каталог Test1.h и libTest1.so, это дает мне ошибку. Если я правильно понимаю, g++ пытается скомпилировать Test1, когда я строю Test2. Поэтому он говорит, что не может найти RInside.h, хотя я не включаю его непосредственно в Test2.

 g++ -I ./shared_1/ ./shared_2/Test2.cc -L./shared_1/ -lTest1_1 -fPIC -shared -o ./shared_2/Test2_3.o

В файле, включенном из ./shared_2/Test2.h:11:0, из ./shared_2/Test2.cc:8: ./shared_1/Test1.h:12:74: фатальная ошибка: RInside.h: Нет такой файл или каталог #include
^ компиляция прекращена.

Что я хочу понять: 1) как отделить код, использующий RInside, от другого проекта/модуля. 2) Что я здесь делаю неправильно?
Я включил здесь какой-то файл на диске Google.

диск

Я пытался искать в Интернете, но не мог понять. Мне определенно чего-то не хватает, чтобы понять. Кто-нибудь может помочь.


person rajeswar    schedule 16.02.2018    source источник
comment
Ваш вопрос довольно сбивает с толку, но заголовочные файлы не имеют ничего общего с библиотеками.   -  person xaxxon    schedule 16.02.2018
comment
Думаю, я понял. Я экспериментировал с примерами, приведенными с RInside. Почти во всех примерах #include ‹Rinside.h› помещается в файлы .cpp, а не в файлы .h. Я помещал эту строку включения в Test1.h. Теперь я заменил эту строку и сохранил ее в Test1.cpp и все пересобрал. это только что сработало. Я пробовал это почти день. Я действительно не знаю разницы. Я изменил изменения и снова перестроил ту же проблему. Значит, с этим что-то должно быть.   -  person rajeswar    schedule 16.02.2018


Ответы (1)


Когда вы включаете test1.h из test2.h, вы также включаете Rinside.h, потому что test1.h включает его.

Не включайте Rinside.h в test1.h, но включайте его в test1.cc, таким образом вы сконструируете свою систему таким образом, что единственным исходным файлом, зависящим от библиотеки Rinside, будет test1.cc. Любой другой источник, использующий функциональность из test1, будет использовать только то, что находится внутри test1.h, эффективно создавая слой, необходимый для абстрагирования RInside.

person simurg    schedule 16.02.2018
comment
Большое спасибо simurg и xaxxon. Теперь я понимаю, почему это сработало во второй раз. Все программы, которые я когда-либо читал, в основном включали внешние библиотеки в файлах .h, поэтому я следовал этому. Простая деталь тоже очень важна. Извините за публикацию большого вопроса. У меня действительно есть проблема, не зная этого. Хорошо, что я узнал что-то новое. Действительно Спасибо Еще раз. - person rajeswar; 16.02.2018