调用程序中对库类成员的未定义引用错误

2024-04-27

下面添加了其他问题,2011 年 4 月 11 日

我正在用 C++ 开发一组跨平台的共享库 DLL/Sos 和测试程序,尽管我必须能够支持 C。这些库将仅作为目标代码发布,但测试程序将随源代码一起发布,因此我们的客户可以获得示例代码。因此,我正在设计要在运行时加载的库,即使用 dlopen()/LoadLibraryA() 进行动态链接。

我在 Umbutu 10.04 上使用 g++ 4.4.3-4,在 Vista/64 上使用 VC++ 2008(32 位模式)。

一切似乎在 Windows 上运行得很好(现在)。然而,当我在 Linux 上编译时,我遇到了一些我无法弄清楚的错误。

测试器和库有几个用多个 .cpp 和 .h 编码的类。除了主要入口点之外,库中的类和大多数内容都位于命名空间 DISCOVER_NS 中。

以下是该项目的简要概述:

首先,承认,我缩短了一些名称,以便代码更具可读性。

发现.cpp

  • 创建一个带有指向它的指针的类对象,称为 DiscoverObject 类型的 theMainObject。

  • 有一个 extern“C”函数,将 MainObject 作为 void* 返回给调用者程序。

  • DiscoverObject 有多种方法,并实例化在单独的 cpp 和 .h 中找到的其他类。一种特殊的方法名为 Hello(),它会执行您所期望的操作,它会打印一条“hello”测试消息。


测试程序.cpp

  • 获取库的句柄

  • 获取指向返回 theMainObject 的函数的函数指针。

  • 执行函数(指针)并将返回的地址从 void* 转换为 DISCOVER_NS::DiscoverObject* aDiscoverObject。

  • 运行aDiscoverObject->Hello()。


我编译:

抄送=@g++

gflags = -g3

cflags = -fPIC -Wall -pedantic

lib_linkflags := -shared -fPIC -lstdc++ -lrt -lpthread -rdynamic

tester_linkflags := -ldl -lpthread

定义 = -D_linux_ -D_DEBUG -D_IPC_ARCH_INTEL=1 -D_THREAD_SAFE


现在,当我编译时,我收到以下错误: *Tester.cpp:142: 对 `Discover_NS::DiscoverObject::hello()' 的未定义引用*

我还从 discovery.so 收到了一堆其他未定义的引用错误,例如: *discover.so:对 `Discover_NS::DeviceList::~DeviceList()* 的未定义引用


我已经尝试过在SO extern“C”中制作几乎所有内容。没有不同。

我尝试将语句放入 discovery.cpp 中,如下所示: extern void Discover_NS::OtherClass::method( args ); 但这给了我关于“类外声明不是定义”错误的错误。


我知道查看代码会有所帮助,但我需要时间敲出一些小东西来发布。

任何人都可以提供解决这个混乱的想法吗?

Thanks,

Wes

德米特里的解决方案并不完全是解决方案的全部,但却是解决方案中的必要元素。在检查我的 makefile 时,我发现了几行无意中重复的行(我将其删除),以及两个“打字错误”,其中 -o 的编码路径错误,并被编码到了编译步骤中。断断续续的步骤编译了logger.cpp和RemException.cpp:

./common/logger.o : ./common/logger.cpp
    $(CC) $(gflags)  $(cflags) -c  $(defines)  -I ./common  
        -I ./EdgeIO  -I ./Discover   
        -o ./common/Debug/logger.o   <+++++++++ path to .o was wrong
        ./common/logger.cpp   2>&1  | tee ./RemKonTester/logger.ERR

然后我发现了真正的错误。我完全忽略了这样一个事实:我没有在 Discover 目录中编译所有 .cpp!。花了一个小时才删除所有的小问题,但现在她从 makefile 中恢复过来了。

原始问题的新版本:现在我知道它可以通过 makefile 工作,我如何让 Eclipse 执行与 makefile 相同的操作?

谢谢德米特里。

Wes

嗯,我的问题仍然在这里。

我已经根据 Dmitry (@Dmitry) 的建议编译了我的代码。只是,它们似乎引起了一个单独的问题。我希望我的库在运行时动态链接到主测试程序。添加-l 发现 -l EdgeIO到链接可以编译所有内容,但它给了我静态链接。

仅供参考,未使用的“pi”是 SO 中包含浮点数,因此将使用浮点支持进行编译。如果调用者想要使用浮点数,则为必需。有人有更好的方法来强制 g++ 进行包含浮点的编译吗?

在修复了 Dmitry 帮助我找到的许多错误后,我现在得到以下输出:

make
./Discover/dllmain.cpp: In function ‘void InitalizeLibraryServices()’:
./Discover/dllmain.cpp:175: warning: unused variable ‘pi’


./EdgeIO/dllMain.cpp: In function ‘void InitalizeLibraryServices()’:
./EdgeIO/dllMain.cpp:158: warning: unused variable ‘pi’


linking RemKonTester
    gflags = -g3
    tstlinkflags = -ldl  -lpthread 
    defines =  -D__linux__   -D_DEBUG   -D_IPC_ARCH_INTEL=1   -D_THREAD_SAFE

./RemKonTester/Debug/RemKonTester.o: In function `main':
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:81: undefined 
    reference to `RemKon_EdgeIO::EdgeIoObject::hello()'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:111: undefined 
    reference to `RemKon_Discover::DiscoverObject::hello()'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:116: undefined 
    reference to `RemKon_Discover::DiscoverObject::SetLogLevel(unsigned int)'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:117: undefined 
    reference to `RemKon_Discover::DiscoverObject::hello()'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:118: undefined 
    reference to `RemKon_Discover::DiscoverObject::LocalIpAddress(int)'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:122: undefined 
    reference to `RemKon_Discover::DiscoverObject::RegisterCallback(bool(*)
    (void*), void*)'
/home/wmiller/Projects/Eclipse/./RemKonTester/RemKonTester.cpp:123: undefined 
    reference to `RemKon_Discover::DiscoverObject::Search()'

collect2: ld returned 1 exit status

我从 Eclipse 收到相同的错误消息集。

RemKonTester.cpp 包含声明这些项目的所有 .h。我已经用 extern "C" 声明尝试过它们,但没有。

希望得到帮助,

Wes


你的问题似乎是-l<library>:

$(CC)  $(gflags)  $(tstlinkflags) $(defines)      -L ./Debug    -ldiscover   
        -ledgeio -o ./Debug/RemKonTester  ./RemKonTester/Debug/RemKonTester.o  
        ./RemKonTester/Debug/logger.o  ./RemKonTester/Debug/libraryClass.o   
        2>&1  | tee ./RemKonTester/make.ERR

它们应该位于目标文件之后,因为链接器会在命令行遇到它们时加载它们并搜索未定义的符号。

See man ld(具体来说-l选项)了解更多信息:

-l 名称规范

...

链接器只会在命令行指定的位置搜索存档一次。如果存档定义了 在命令行上的存档之前出现的某个对象中未定义的符号,链接器将包括 档案中的适当文件。但是,稍后出现在命令行上的对象中的未定义符号不会导致 链接器再次搜索存档。

这应该适合你:

$(CC) $(gflags) $(tstlinkflags) $(定义) -L ./Debug -o ./Debug/RemKonTester ./RemKonTester/Debug/RemKonTester.o ./RemKonTester/Debug/logger.o ./RemKonTester/调试/libraryClass.o-ldiscover -ledgeio2>&1 |三通 ./RemKonTester/make.ERR

附:请注意,StackOverflow 中有一个用于编辑问题的选项,发布附加信息作为答案并不是一个好的做法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调用程序中对库类成员的未定义引用错误 的相关文章

  • CMake 找不到请求的 Boost 库

    既然我已经浏览了其他人的解决方案几个小时 但找不到适合我的问题的正确答案 我想将我的具体问题带给您 我正在尝试使用 CMake 构建 vsomeip 为此 我之前构建了 boost 1 55 但是 我在 CMake 中收到以下错误 The
  • 在路由mvc 4中添加公司名称

    我一直在尝试为 Facebook 等用户提供在 URL 中添加公司名称的选项 http localhost 50753 MyCompany Login 我尝试过不同的网址 但没有成功 routes MapRoute name Default
  • 如何在另一个应用程序中挂钩 api 调用

    我正在尝试挂钩另一个应用程序的 ExtTextOut 和 DrawTextExt GDI 方法调用 我知道我需要使用 GetProcAddress 来查找 gdi32 dll 中那些方法的地址 并用我的函数的地址覆盖我想要挂钩的进程中的地址
  • 删除是如何工作的? [复制]

    这个问题在这里已经有答案了 可能的重复 C 编程 free 如何知道要释放多少 https stackoverflow com questions 1518711 c programming how does free know how m
  • 在现代 C++ 中,临时生命周期延长何时有用?

    在 C 中 您可以将函数的返回值 返回值 而不是引用 绑定到 const 引用 并且代码仍然有效 因为该临时对象的生命周期将延长到作用域末尾 例如 std string get string return abc void f const
  • linq 中使用字符串数组 c# 的 'orderby'

    假设我有一个这样的方法定义 public CustomerOrderData GetCustomerOrderData string CustomerIDs var query from a in db Customer join b in
  • 从代码中,如何创建对存储在附加属性中的对象的属性的绑定?

    我们有一个继承的附加属性来存储一个对象 在可视化树的更下方 我们希望从代码绑定到该对象的属性 通常我们像这样构建绑定的路径部分 var someBinding new Binding Path new PropertyPath Attach
  • 运行需要 MySql.Data 的内置 .NET 应用程序

    我在运行我编写的内置 NET 应用程序时遇到问题 我的应用程序使用最新的 MySql 连接器 该连接器安装在我的系统上 当我尝试将其添加为引用时 该连接器显示为 NET 4 Framwork 组件 当我在环境中以调试模式运行应用程序时 一切
  • 在开关中使用“goto”?

    我看到了一个建议的编码标准 内容如下Never use goto unless in a switch statement fall through 我不跟 这个 例外 案例到底是什么样的 这证明了goto 此构造在 C 中是非法的 swi
  • 如何制作可启动程序?

    所以 这个问题可能看起来很奇怪 但假设我编译了 int main void int x 3 int y 4 int z x y 是否可以让CPU这样运行 如何 例如 这允许我写入监视器吗 如果我没记错的话 内存中有些地方可以写入要显示的内容
  • 一元 +/- 运算符如何可能导致“-a”或“+a”中的整数提升,“a”是算术数据类型常量/变量?

    这句看似微不足道的台词摘自我的迈克 巴纳汉和布雷迪的 C 书 第 2 8 8 2 节 http publications gbdirect co uk c book chapter2 expressions and arithmetic h
  • C# 开源 NMEA 解析器 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找 C 开源 NMEA 解析器 嗯 我自己也不熟悉 但是一些快速搜索显示了一个代码项目 htt
  • 访问 ascx 文件中的母版页控件

    我有一个母版页文件 其中包含 2 个面板控件中的 2 个菜单 我还使用控件来检查用户是否登录并获取用户类型 根据我想要显示 隐藏面板的类型 控件本身不在母版页中引用 而是通过 CMS 系统动态引用 我想在用户控件中使用findcontrol
  • C# 编译器不会优化不必要的强制转换

    前几天 在写答案的时候这个问题 https stackoverflow com questions 2208315 why is any slower than contains在这里 关于溢出 我对 C 编译器感到有点惊讶 它没有按照我的
  • MFC:如何设置CEdit框的焦点?

    我正在开发我的第一个简单的 MFC 项目 但我正在努力解决一个问题 想要设置所有的焦点CEdit其中一个对话框中的框 我的想法是 当打开对话框时 焦点位于第一个编辑框上 然后使用 选项卡 在它们之间交换 我看到了方法SetFocus 但我无
  • 如何从 Rx Subscribe 回调异步函数?

    我想回调 Rx 订阅中的异步函数 例如 像那样 public class Consumer private readonly Service service new Service public ReplaySubject
  • ASP.NET MVC 路由:如何从 URL 中省略“索引”

    我有一个名为 StuffController 的控制器 具有无参数索引操作 我希望从表单中的 URL 调用此操作mysite com stuff 我的控制器定义为 public class StuffController BaseContr
  • 在 C#.NET 中安全删除文件

    在我正在做的一个项目中 我想为用户提供 安全 删除文件的选项 例如 用随机位或 0 覆盖它 在 C NET 中是否有一种简单的方法可以做到这一点 效果如何 你可以调用系统内部删除 http technet microsoft com en
  • 如何调试 .NET 运行时中的内部错误?

    我正在尝试调试一些处理大文件的工作 代码本身works 但 NET 运行时本身会报告零星错误 对于上下文 这里的处理是一个 1 5GB 文件 仅加载到内存中一次 在循环中处理和释放 故意尝试重现此否则不可预测的错误 我的测试片段基本上是 t
  • 为什么以下 C 程序会出现总线错误?

    我认为这是第一个失败的 strtok 调用 好久没写C了 有点不知所措 非常感谢 include

随机推荐