LINUX.ORG.RU

Компиляция программы на срр из нескольких файлов


0

0

Есть два файла. test.cpp:

#include <iostream> extern char *getstr(); int main() { std::wcout << getstr() << std::endl; return 0; }

test2.cpp:

wchar_t *getstr() { return L"string"; }

Компилирую и собираю их коммандой gcc test.cpp test2.cpp -o test -lstdc++

Запускаю программу, она выводит одну букву s. В чем проблемма?

Ответ на: комментарий от gpg

Я понял в чем ошибка. Спасибо. Заменил на

extern wchar_t *getstr();

Что такое _char_? Почему компилятор не выдал сообщения об ошибке? Может есть опция...

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

> Что такое _char_?

с помощью _ тебе подчеркнули ошибку

> Почему компилятор не выдал сообщения об ошибке?

это дело линкера

> Почему компилятор не выдал сообщения об ошибке? Может есть опция...

обычно именно для решения этой проблемы используются .h файлы.

Так как он одинаков и инклудятся везде, то компилятор увидит если есть несоответствия

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

> Почему компилятор не выдал сообщения об ошибке?

Тип возвращаемого значения не входит в сигнатуру метода в C++. Опции нет. Это стандарт. Именно поэтому у тебя всё слинковалось, иначе бы линковщик выдал "unresolved symbol".

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

Спасибо. Вроде из статическими библиотеками разобрался... Но у меня возникла проблемма из динамическими. Есть файл test2:

wchar_t *getstr()

{

return L"string";

}

Компилирую его командой gcc test2.cpp -shared -o libtest.so -fPIC

Далее файл test.cpp:

#include <iostream>

#include <dlfcn.h>

int main()

{

void *lib = dlopen("./libtest.so", RTLD_LAZY);

std::wcout << L"Lib: " << lib << std::endl;

wchar_t *(*getstr)() = (wchar_t *(*)())dlsym(lib, "getstr");

std::wcout << L"getstr: " << getstr << std::endl;

std::wcout << getstr() << std::endl;

dlclose(lib);

return 0;

}

Компилирую gcc test.cpp -lstdc++ -ldl -o test Запускаю... Выводится

Lib: 0x603030

getstr: 0

Segmentation fault

Что я не так?

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

Кратко: дело в name mangling'е. Надеюсь, пример ниже будет понятен.
В дополнение скажу, что стандарта на name mangling нет, поэтому обычно
лучше использовать extern "C".

===== BEGIN testso.cpp =====
extern "C" char* getstr()
{
    return "test string";
}

char* getstrCpp()
{
    return "cpp string";
}
===== END testso.cpp =====

===== BEGIN testbin.cpp =====
#include <iostream>
#include <dlfcn.h>

using namespace std;

typedef char* (*FuncType)();

int main()
{
    void* lib = dlopen( "./libtestso.so", RTLD_LAZY );
    cout << "lib: " << lib << endl;
    FuncType getstr = (FuncType)dlsym( lib, "getstr" );
    cout << "getstr: " << (void*)getstr << endl;
    if( getstr )
        cout << "result: '" << getstr() << "'" << endl;
    getstr = (FuncType)dlsym( lib, "_Z9getstrCppv" );
    cout << "getstrCpp: " << (void*)getstr << endl;
    if( getstr )
        cout << "resultCpp: '" << getstr() << "'" << endl;
    return 0;
}
===== END testbin.cpp =====

===== BEGIN SConstruct =====
SharedLibrary( target = "testso",
               source = [ "testso.cpp", ])

Program( target = "testbin",
         source = [ "testbin.cpp", ],
         LIBS = [ "dl", ])
===== END SConstruct =====

$ scons -Q
g++ -o testso.os -c -fPIC testso.cpp
g++ -o libtestso.so -shared testso.os
g++ -o testbin.o -c testbin.cpp
g++ -o testbin testbin.o -ldl
$ ./testbin
lib: 0x804a020
getstr: 0xb7f1449c
result: 'test string'
getstrCpp: 0xb7f144b2
resultCpp: 'cpp string'
$ nm libtestso.so |grep getstr
000004b2 T _Z9getstrCppv
0000049c T getstr

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

Спасибо. Разобрался с name mangling, по крайней мере понял что это такое... По какому слову нужно гуглить, чтобы найти про SConstruct?

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