在.h文件中使用非常简单的C++函数链接错误

Neo*_*Man 5 c++ linker compiler-errors visual-studio

我已经做了两个函数来将一个32/64位指针"转换"成一个双精度型.单独使用时代码工作(只有.h和包含它的.cpp),但在其他地方使用.h(复制到项目目录然后包含)时,会对所有函数抛出"已定义"错误.链接时的h文件.

.h文件的源代码如下:

#pragma once
#ifndef __FLOATCAST_H
#define __FLOATCAST_H

//A quick and dirty way of casting pointers into doubles and back
//Should work with BOTH 64bit and 32bit pointers
union ptr_u {
    double d;
    void* p;
};

double ptr2double(void* pv){
    ptr_u ptr;
    ptr.p = pv;
    return (ptr.d);
};

void* double2ptr(double dv){
    ptr_u ptr;
    ptr.d = dv;
    return(ptr.p);
};

#endif
Run Code Online (Sandbox Code Playgroud)

该链接表示这些函数已经在文件源文件(而不是他的.obj)上定义,该文件不包含此文件.

编辑:为什么我想要一个指针内部双?因为我需要Lua(5.1)来回调一个对象成员函数.

Edit2:Lua提供了一种存储用户数据的方式,它似乎是足够的解决方案,而不是投射指针(见注释)

Arm*_*yan 8

内联标记您的功能

inline double ptr2double(void* pv){
    ptr_u ptr;
    ptr.p = pv;
    return (ptr.d);
};

inline void* double2ptr(double dv){
    ptr_u ptr;
    ptr.d = dv;
    return(ptr.p);
};
Run Code Online (Sandbox Code Playgroud)

您可以看到,当您在两个单独的源文件(翻译单元)中包含相同的功能时,您将获得多个定义.您通常有两种选择:

  • 在.h文件中修改您的功能,在单独的.cpp文件中修改定义
  • 使您的函数内联并将它们保存在.h文件中

C++的单定义规则禁止非内联函数的多个定义.

编辑:#ifdef警卫警惕多重纳入一个单一的源文件.但您确实可以将.h文件包含在不同的.cpp文件中.ODR适用于整个程序中的定义,而不仅仅是单个文件.

EDIT2 经过一些评论后,我觉得我必须在这里加入这条信息,以免产生任何误解.在C++中,有关内联函数和非内联函数的不同规则,例如ODR的特殊情况.现在,您可以将任何函数(无论是长函数还是递归函数)标记为内联函数,并且特殊规则将适用于它们.编译器是否决定实际内联它(即代替代码而不是调用)是完全不同的事情,即使你没有将函数标记为内联,它也可以做,并且可以决定不做即使你将其标记为内联.