Как преобразовать 32-разрядное целое число со знаком в 64-разрядное целое число со знаком в C - PullRequest
3 голосов
/ 27 марта 2019

У меня есть библиотека, которая скомпилирована для использования 32-битного целого числа со знаком.Когда другие приложения компилируют свои с флагом, например: -DODBC64, это продвигает тот же тип, который я использовал в моей библиотеке, в 64-битное целое число со знаком.Например:

 #ifdef ODBC64
       typedef sint64 SLEN;
 #else
       #define SLEN int
 #endif

Когда приложение передает ссылку на мою библиотеку как:

SLEN count;
mylibraryfunction(&count);

значения, возвращаемые приложению, выглядят так:

sizeof(SLEN) = 8
sizeof(SLEN) in my library = 4
m_AffectedRows BEFORE = 0x3030303030303030
m_AffectedRows AFTER = 0x3030303000000000        0

Вы можетевижу, что назначение из моей библиотеки копирует 4 байта (значение 0).Мне нужно знать способ сброса старших 4 байтов в 0. Например:

0x0000000000000000

Я пробовал и static_cast, и reinterpret_cast, но ни один из них не помог.

Ответы [ 2 ]

1 голос
/ 27 марта 2019

Я сделал 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: вне доступа с возможными более катастрофическими последствиями.

0 голосов
/ 27 марта 2019

Ваша библиотека не может получить доступ к старшим 4 байтам, но вы можете это сделать, прежде чем ее вызвать. Поэтому попробуйте сначала инициализировать его с 0:

SLEN count = 0; // initialize with 0's
mylibraryfunction(&count);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...