我有一个使用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
您可以看到我lib中的分配正在复制4个字节(值0)。 我需要知道一种将高4字节重置为0的方法。 例如:
0x0000000000000000
我尝试了static_cast和reinterpret_cast,但是都没有帮助。
答案 0 :(得分:1)
我制作了一个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
这非常危险!任何外部符号的使用都应使用100%兼容的声明。 (是的,C和C ++提供了多种方法来射击自己的脚。)
想象一下,如果lib.cc函数func()
会写int64_t
,而prog.cc将传递指向int32_t
的指针,那将会发生什么:超出范围的访问可能会带来更严重的后果
答案 1 :(得分:0)
您的库无法访问高4个字节,但是您可以在调用它之前访问。因此,尝试使用0的第一个进行初始化:
SLEN count = 0; // initialize with 0's
mylibraryfunction(&count);