c++ - .h 文件上非常简单的函数 C++ 的链接错误

标签 c++ visual-studio linker compiler-errors

我创建了两个函数来将 32/64 位指针“转换”为 double 。该代码在单独使用时有效(只有 .h 和一个 .cpp 包括它)但是当在其他地方使用 .h 时(复制到项目目录然后包含)它会为 .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

该链接表示函数已在不包含此文件的文件源文件(而不是他的 .obj)中定义。

编辑: 为什么我想要一个 pointer-inside-double?因为我需要Lua(5.1)来回调一个对象成员函数。

编辑2: Lua 提供了一种存储用户数据的方法,这似乎是一个足够的解决方案,而不是强制转换指针(见评论)

最佳答案

将你的函数标记为内联

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);
};

你看,当你在两个单独的源文件(翻译单元)中包含相同的函数时,你会得到多个定义。您通常有 2 个选择:

  • 在 .h 文件中对函数进行说明,在单独的 .cpp 文件中进行定义
  • 使您的函数内联并将它们保存在 .h 文件中

C++ 的单一定义规则禁止非内联函数的多重定义。

编辑: #ifdef 防止多次包含到一个单个 源文件中。但是您确实可以将 .h 文件包含到不同的 .cpp 文件中。 ODR 适用于整个程序中的定义,而不仅仅是单个文件。

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

关于c++ - .h 文件上非常简单的函数 C++ 的链接错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6424911/

相关文章:

linker - 用于制作库的 ranlib、ar 和 ld 之间有什么区别

linux - 在 Linux 上使用静态链接的应用程序有什么缺点吗?

c - Mex 链接 visa32.lib

C++:从 64 位进程注入(inject) 32 位目标

visual-studio - 如何在 VS 2010 中默认停止文件夹作为命名空间提供程序?

c++ - 允许在没有 Active Directory 信任的情况下进行 winhttp 委派

asp.net - asp.net 中程序 Crystal 报告的正确形式是什么?和视觉基础

c# - 单元测试 - 扩展 Visual Studio 单元测试类型 - 不工作

c++ - NITE2::UserTracker 在读取 oni 文件时崩溃

c++ - 双核机器上的多线程?