LINUX.ORG.RU

Различие компиляции динамических библиотек gcc и g++


0

0

http://www.firststeps.ru/linux/

Шаг 8 - Функции работы с динамическими библиотеками

main.c я немножко изменил

#include <stdio.h>

/* заголовочный файл для работы с динамическими библиотеками */
#include <dlfcn.h>

int main(int argc, char* argv[]){

	void *ext_library;	// хандлер внешней библиотеки
	double value=0;		// значение для теста
	double (*powerfunc)(double x);	// переменная для хранения адреса функции

	//загрузка библиотеки
	ext_library = dlopen("./libpowers.so",RTLD_LAZY);
	if (!ext_library){
		//если ошибка, то вывести ее на экран
		fprintf(stderr,"dlopen() error: %s\n", dlerror());
		return 1;
	};

	//загружаем из библиотеки требуемую процедуру
	powerfunc = (double (*)(double))dlsym(ext_library, argv[1]);	
	value=3.0;

	//выводим результат работы процедуры
	printf("%s(%f) = %f\n",argv[1],value,(*powerfunc)(value));

	//закрываем библиотеку
	dlclose(ext_library);
};

lib.c такой же как на сайте

double power2(double x){
	return x*x;
};

double power3(double x){
	return x*x*x;
};

double power4(double x){
	return power2(x)*power2(x);
};

компилируем так же как на сайте

gcc -fPIC -c lib.c
gcc -shared lib.o -o libpowers.so
gcc main.c -o main -ldl
ошибок нет

вызываем ./main power2 все работает правильно

а если скомпилировать c помощью g++

mv lib.c lib.cpp
mv main.c main.cpp
g++ -fPIC -c lib.cpp
g++ -shared lib.o -o libpowers.so
g++ main.cpp -o main -ldl
ошибок нет

вызываем ./main power2 Ошибка сегментирования

я, как истинный виндязутко и создатель dll, негодую =) что же неправильно?



Последнее исправление: puchuu (всего исправлений: 1)

После

powerfunc = (double (*)(double))dlsym(ext_library, argv[1]);

вставь это:

char *error = dlerror();
if (error){
    fprintf(stderr, "%s\n", error);
    exit(EXIT_FAILURE);
}
И запусти.

anon_666
()
Ответ на: комментарий от anon_666

undefined symbol: power2 вот что оно мне сказало

как я понимаю я как то неправильно собираю so с помощью g++ а как надо? в чем собственно говоря отличие от gcc?

puchuu
() автор топика
Ответ на: комментарий от anon_666

называется она _Z6power2d ого какой трабл! значит придется гуглить в сторону этого Name_mangling (>_<)" а в gcc таких проблем нет!

puchuu
() автор топика

Перед объявлением каждой функции пиши extern «C». Это укажет компилятору, что имя символа менять нельзя.

j-a-t-a
()
Ответ на: комментарий от Love5an

Т.е. в таком, казалось бы, низкоуровневом языке, даже нейм мэнглинг не стандартизирован, и у каждого компилятора угребищней другого.

Love5an
()
Ответ на: комментарий от anon_666

ты не можешь линковаться с библиотекой, собранной g++, используя msvc.

если собирать gcc (язык c), то все ок.

mono ★★★★★
()

> я, как истинный виндязутко и создатель dll, негодую =)

У виндузятников те же самые проблемы. Выходит, что вы товарищ - проходимец!

anonymous
()
Ответ на: комментарий от anon_666

> http://en.wikipedia.org/wiki/Name_mangling

Спасибо, не знал что и так можно.

Т.е. я не могу линковаться с помощью gcc с библиотекой слинкованой icc, например?

Этот с умным видом рассуждает про name mangling, но спалился на extern «C» и особенностях линковки цпп-шного кода. Товарищи школьники, собирайте лучше гербарий к новому учебному году!

anonymous
()
Ответ на: комментарий от anonymous

ну а анонимус то конечно с рождения во всем разбирался и все на свете умел, даже гербарий собирать. берем пример!

mono ★★★★★
()
Ответ на: комментарий от Love5an

С учётом того, что нестандартизирован ABI, различие name mangling - это даже хорошо. При потытке запустить, прогу собранную одним компилером, с либой, собранной другим, лшибки возникнут на этапе загрузки, а не где-то в середине работы.

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

Феерично. Ошибки, не связанные с несовместимостью либ, которой ещё может и не быть - это очень полезные ошибки, да.

Xenesz ★★★★
()
Ответ на: комментарий от Begemoth

А не параллельны ли несовместимость компайлеров и потенциально сломанное ABI? Если ABI заламинируют намертво, что-то изменится?

Xenesz ★★★★
()
Ответ на: комментарий от Love5an

Хочешь сказать в любимом CL имена в shared-libraries стандартизированы? В LW - одно, в Allegro - другое, а в остальные компилеры - так вообще этого не умеют :) Так что не надо гнать на C++.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

CL не претендует на роль низкоуровневого встраиваемого языка.
В тех реализациях, где такое все же возможно, оно все просто идет через интерфейс Си.

Love5an
()
Ответ на: комментарий от Love5an

В тех реализациях, где такое все же возможно, оно все просто идет через интерфейс Си.

И к С++ тоже (например ECL), кстати сказать. Нет ничего страшного в том чтобы написать extern «C» в программе на C++ и не иметь головной боли с именами. Ну да ладно.

quasimoto ★★★★
()
Ответ на: комментарий от Xenesz

Если ABI заламинируют намертво, что-то изменится?

Если разные компиляторы будут следовать одному и тому же ABI, то полученный на выходе исполняемый код будет совместим, и можно будет спокойно собирать программу gcc с использованием библиотек, собранных icc, или в GNU/Linux кросскомпилировать библиотеки для Windows и компоновать с ними программу, собираемую Visual C++.

Begemoth ★★★★★
()
Ответ на: комментарий от Love5an

Какие диалекты нахер?

Раз речь идёт о компиляции, то, безусловно, каждая реализация вводит свой диалект (там так и пишут «our dialect»).

Не притворяйся что не понял.

Не понял ``причин, по которым C++ является срамным говном"

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

>Не понял ``причин, по которым C++ является срамным говном"

к примеру, FBC: http://en.wikipedia.org/wiki/Fragile_base_class
http://2f.ru/holy-wars/fbc.html
http://www.cas.mcmaster.ca/~emil/publications/fragile/
нестабильный АБИ, зависимый от компилятора
различия в поддержке разных фич вроде RTTI, шаблонов, прекомпилированных хедеров,С++0х и т.п. разными компиляторами

что приводит к необходимости такого костыля: http://en.wikipedia.org/wiki/Embedded_C%2B%2B — запретить все «сомнительные» фичи, собственно сам С++

язык шаблонов — хотя он и Тьюринг-полный, и на нём можно реализовать машину Тьюринга http://stackoverflow.com/questions/189172/c-templates-turing-complete или лямбда-исчисление http://en.literateprograms.org/Turing_machine_simulator_(C_Plus_Plus,_Templat... http://matt.might.net/articles/c++-template-meta-programming-with-lambda-calc... http://aszt.inf.elte.hu/~gsd/halado_cpp/ch06s04.html , количество костылей для реализации просто не поддаётся исчислению.

Простыни шаблонов, в которые скатывается случаи применения того же буста

модульности нормальной нет, но есть прекомпилированные хедеры. Правда, большинство людей использует их таким способом, что эффекту от них 0, и как настроить правильно — не знает http://www.cygnus-software.com/papers/precompiledheaders.html .

одна проблема вроде громоздкости шаблонов наслаивается на другую (неоднозначный синтаксис, который чтобы просто распарсить нужно реализовывать семантические предикаты), третью (отсутствие модульности), четвёртую (альтернативное понимание разных компиляторов) — и в итоге имеем долго компилируемое сложное неподдерживаемое г-но.

Фактически С++ — это 3 языка в одном: язык, совместимый с Си, но с добавленными ссылками/константностью; язык шаблонов; симула-подобный ОО язык. И все эти языки хреново друг с другом состыкованы — ни одна сущность вроде шаблонов/классов/си-кода не является по-настоящему сущностью первого порядка.


В общем, С++ — это слишком много костылей.
«Бороду вижу, а философа не вижу» — костыли вижу, а язычок как-то слабоват.

anonymous
()
Ответ на: комментарий от anonymous

сравни, к примеру С++ с Objective-C в плане FBC: http://cocoawithlove.com/2010/03/dynamic-ivars-solving-fragile-base.html или сериализацию на Objective-C http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Archivi... -- прозрачное решение для всех объектов произвольной структуры, на базе plist, как в лиспе, и на С++ (варианты с рефлексией и реализацией ищи сам. Без рефлексии тут сплошные костыли с явным прописыванием всего, в результате при изменении членов класса (man FBC) ломается сериализация и её надо заново переделывать)

anonymous
()
Ответ на: комментарий от quasimoto

ну и ещё тебе пару вопросов по С++:
1. Что означает невиртуальный деструктор, в чём тут ошибка?
2. какая семантика у «константый указатель на константу», «волатильность», почему константность не означает иммутабельности (нетранзитивность)?

anonymous
()
Ответ на: комментарий от anonymous

не вижу в языке действительно полезных фич (сущностей первого порядка, полноценного параметрического полиморфизма, что в конечном итоге выражается в прозрачной, готовой реализации рефлексии/интроспекции/модульности).
Вместо этого вижу много ненужного, запутанно-многословного и нестабильно реализованного. Такое ощущение, что автор не знал чего хотел, в итоге попытался сделать One size fits all, но получилось не это, а kitchensync-дизайн. Много велосипедистов изобретают свои велосипеды на С++, но ниасиливают довести до ума и бросают — использование С++ в таком проекте явно вредно — если бы не С++ проект довели бы до ума. Такое ощущение, что С++ победил здравый смысл.

anonymous
()
Ответ на: комментарий от quasimoto

правда, не делай вид, что не понял. Вот мы не знаем, как конкретно имена будут выглядеть в объектнике, сгенерированном лиспом, если он не интерфейсится в Си, но сами имена-то описаны в ANSI стандарте, составляют ядро языка, и показываются в *FEATURES* конкретной реализации.
Мы не знаем грубо говоря «ABI лиспа», во что выльется конкретный откомпилированный код — ибо «зависит от реализации». Но, можем через alien FFI использовать С ABI либо, как в ECL, сделать прозрачную линковку си-кода и лисп-кода (компилируемого в си).

Сравни, например, Argile http://www.nongnu.org/argile/ — язык компилируется в Си, и за счёт этого прозрачно линкуется с си-кодом. Или, тот же goo. «ABI языка» описывает то, что код должен прозрачно линковатья с Си-кодом, в итоге FFI по большому счёту, не нужен

anonymous
()
Ответ на: комментарий от Begemoth

вообще-то говоря, тот же gnu ld поддерживает много разных выходных форматов, но кажется, не позволяет линковать .obj вместе с .o. Был какой-то «универсальный» линкер, который такое умел. Но это не очень полезно, т.к. каждый особый конпелятор потащит за собой свой libc /crt и другие зависимости.

Годов до середины 90-х формат .obj был стандартизирован, потом пошли кто в лес, кто по дрова.

Под D, кажется был проект DDL где ребята сами реализовали свой линкер и грузили ELF под Windows или .so из-под Linux (потому что стандартный .dll убог по возможностям, да). Но там всё делалось вручную — фактически они написали свой загрузчик и линкер.

Я так понимаю, просто никому нет дела до бинарной совместимости и стабильного ABI.

anonymous
()
Ответ на: комментарий от anonymous

Я так понимаю, просто никому нет дела до бинарной совместимости и стабильного ABI.

Просто люди хотят решать прикладные задачи сейчас, а не когда стандарт на ABI будет выработан и реализован, поэтому все кому действительно нужно использование различных компиляторов и/или языков полагаются на ABI ОС или доминирующей на целевой платформе реализации языка С. А с учётом разницы в системах типов языков программирования стандартизация ABI для С++ вряд ли имеет смысл - всё равно библиотеки на С++ без дополнительной прослойки можно будет использовать только из С++.

Begemoth ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.