Я сделал MCVE, где я напоминал то, что происходит в случае OP.
Мне даже не потребовалась дополнительная библиотека для этого, только две единицы перевода (в результате два объектных файла).
Первый lib.cc
:
#include <cstdint>
extern "C" void func(int32_t *pValue);
void func(std::int32_t *pValue)
{
*pValue = 0;
}
Второй prog.cc
:
#include <iostream>
#include <iomanip>
// how prog.cc "knows" func():
extern "C" void func(int64_t *pValue);
int main()
{
int64_t value = 0x0123456789ABCDEFull;
std::cout << "value before: " << std::hex << value << '\n';
func(&value);
std::cout << "value after : " << std::hex << value << '\n';
return 0;
}
Ошибки компилятора?Нет. Каждая единица перевода использует прототип func()
.
Ошибки компоновщика?Нет. Символы совпадают, все остальное за пределами видимости компоновщика.
Я должен признать, что для этого мне пришлось использовать extern "C"
.В противном случае, по крайней мере, искажение имени в C ++ помешало правильному связыванию.(Когда я узнал об этом, я сделал код на языке C).
Вывод:
value before: 123456789abcdef
value after : 123456700000000
Live Demo on wandbox
Это очень опасно! Любое использование любого внешнего символа должно использовать 100% совместимое объявление.(И да, C и C ++ предоставляют различные способы выстрелить себе в ногу.)
Представьте, что произойдет, если функция lib.cc func()
напишет int64_t
, где prog.ccпередаст указатель на int32_t
: вне доступа с возможными более катастрофическими последствиями.