- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
一般来说对 linux 来说非常新,并试图构建一个可加载的模块以在 zabbix 中使用,这有效,但试图构建一个简单的 shell 程序来测试它。这意味着该模块需要动态加载。
可共享模块 SNMPmath 是用这个构建的:
gcc -shared -o SNMPmath.so $(CFLAGS) -I../../../include -I/usr/include/libxml2 -fPIC SNMPmath.c
这适用于 zabbix。
测试程序(TestSO.c)使用
lib_handle = dlopen("./SNMPmath.so", RTLD_NOW);
动态加载此图像,当它加载时,它缺少符号,包括来自 SNMPmath 可加载模块中引用的 net-snmp 包的 init_snmp。
我的问题既笼统又具体。什么是正确的方法——这个由可加载模块调用的库是否应该被强制进入可加载模块?它是否应该被强制进入测试程序(尽管没有编译时引用它)?或者它本身应该动态加载到可加载模块中(这似乎与我在其他示例中看到的相矛盾)?
在任何一种情况下,如何修改 GCC 命令以包含 net-snmp?我已经尝试了整个存档的变体,不需要,列出了我认为是库(/usr/lib/x86_64-linux-gnu/libsnmp.a)的各种编译器选项,但没有效果(或偶尔出错) ).还尝试链接到该版本的 .so 版本(无效)。因此,关于包含该库的正确 GCC 命令的提示将非常有帮助。
这是链接主程序的一次迭代尝试:
gcc -rdynamic -o TestSO -I../../../include -I/usr/include/libxml2 TestSO.c -ldl -Wl,--no-as-needed /usr/lib/x86_64-linux-gnu/libsnmp.so
我发现了许多加载模块的示例,但它们都加载了一个简单的例程,该例程本身没有需要满足的 undefined symbol 。
回顾:
TestSO.c
==> Loads with dlopen SNMPmath.c
==> needs to refer to net-snmp routines like init_snmp
欢迎指出示例或解释,我意识到我遗漏了一些相当明显的东西。
在第一条评论后进行编辑以包括:
我现在可以正常使用了,但如果这是正确的,我将不胜感激。我将其删减以显示整个代码。这是生成 SO 的代码:
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <string.h>
int zbx_module_SNMPmath_avg(int i, int j)
{
init_snmp("snmpapp"); // initialize SNMP library
return 1;
}
这是它的编译方式(注意名称略有变化):
CFLAGS=-I. `net-snmp-config --cflags`
SNMPmath_small: SNMPmath_small.c
gcc -shared -o SNMPmath.so $(CFLAGS) -I../../../include -I/usr/include/libxml2 -fPIC SNMPmath_small.c -Wl,--no-as-needed,/usr/lib/x86_64-linux-gnu/libsnmp.so
然后是主程序:
#include <stdio.h>
#include <dlfcn.h>
#include <dlfcn.h>
#include <string.h>
int main(int argc, char **argv)
{
void *lib_handle;
int(*fn)(int req, int ret);
int x;
char *error;
lib_handle = dlopen("./SNMPmath.so", RTLD_NOW);
if (!lib_handle)
{
fprintf(stderr, "Error on open - %s\n", dlerror());
exit(1);
}
else
fprintf(stderr,"Successfully loaded module\n");
fn = dlsym(lib_handle, "zbx_module_SNMPmath_avg");
if ((error = dlerror()) != NULL)
{
fprintf(stderr, "Error on dlsym %s\n", error);
exit(1);
}
else fprintf(stderr,"Successfully called dlsym\n");
// testing
int req, ret;
req=1;
ret=1;
x=(*fn)(req, ret);
printf("Valx=%i\n",x);
dlclose(lib_handle);
return 0;
}
最后这是用:
TestSO: TestSO.c
gcc -rdynamic -o TestSO -I../../../include -I/usr/include/libxml2 TestSO.c -ldl
这现在将按预期运行。我发现在构建我的 so 时链接到 netsnmp 库的 so 文件似乎可行。
但这是正确的顺序吗?和/或首选顺序?
附言。关闭以阅读第一个建议答案中的论文。
最佳答案
指向解释的指针:Drepper's paper: Howto write shared libraries
但我们需要更多的源代码(以及用于编译它的命令)和真正的错误消息(例如,在 dlopen
调用之后由 dlerror()
给出)帮助更多。
(另见 this answer)
您可能想添加一些库,例如 -lsomething
(我不知道哪个,您可能知道!)到您正在构建的命令 gcc -shared
SNMPmath.so
....您不想将静态库(例如libsnmp.a
)链接到它(您应该将共享库链接到您的SNMPmath.所以
共享对象)。
关于c - Ubuntu C 程序可加载模块和 undefined symbol ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21706421/
我是 C 语言新手,我编写了这个 C 程序,让用户输入一年中的某一天,作为返回,程序将输出月份以及该月的哪一天。该程序运行良好,但我现在想简化该程序。我知道我需要一个循环,但我不知道如何去做。这是程序
我一直在努力找出我的代码有什么问题。这个想法是创建一个小的画图程序,并有红色、绿色、蓝色和清除按钮。我有我能想到的一切让它工作,但无法弄清楚代码有什么问题。程序打开,然后立即关闭。 import ja
我想安装screen,但是接下来我应该做什么? $ brew search screen imgur-screenshot screen
我有一个在服务器端工作的 UDP 套接字应用程序。为了测试服务器端,我编写了一个简单的 python 客户端程序,它发送消息“hello world how are you”。服务器随后应接收消息,将
我有一个 shell 脚本,它运行一个 Python 程序来预处理一些数据,然后运行一个 R 程序来执行一些长时间运行的任务。我正在学习使用 Docker 并且我一直在运行 FROM r-base:l
在 Linux 中。我有一个 c 程序,它读取一个 2048 字节的文本文件作为输入。我想从 Python 脚本启动 c 程序。我希望 Python 脚本将文本字符串作为参数传递给 c 程序,而不是将
对于一个类,我被要求编写一个 VHDL 程序,该程序接受两个整数输入 A 和 B,并用 A+B 替换 A,用 A-B 替换 B。我编写了以下程序和测试平台。它完成了实现和行为语法检查,但它不会模拟。尽
module Algorithm where import System.Random import Data.Maybe import Data.List type Atom = String ty
我想找到两个以上数字的最小公倍数 求给定N个数的最小公倍数的C++程序 最佳答案 int lcm(int a, int b) { return (a/gcd(a,b))*b; } 对于gcd,请查看
这个程序有错误。谁能解决这个问题? Error is :TempRecord already defines a member called 'this' with the same paramete
当我运行下面的程序时,我在 str1 和 str2 中得到了垃圾值。所以 #include #include #include using namespace std; int main() {
这是我的作业: 一对刚出生的兔子(一公一母)被放在田里。兔子在一个月大时可以交配,因此在第二个月的月底,每对兔子都会生出两对新兔子,然后死去。 注:在第0个月,有0对兔子。第 1 个月,有 1 对兔子
我编写了一个程序,通过对字母使用 switch 命令将十进制字符串转换为十六进制,但是如果我使用 char,该程序无法正常工作!没有 switch 我无法处理 9 以上的数字。我希望你能理解我,因为我
我是 C++ 新手(虽然我有一些 C 语言经验)和 MySQL,我正在尝试制作一个从 MySQL 读取数据库的程序,我一直在关注这个 tutorial但当我尝试“构建”解决方案时出现错误。 (我正在使
仍然是一个初学者,只是尝试使用 swift 中的一些基本函数。 有人能告诉我这段代码有什么问题吗? import UIKit var guessInt: Int var randomNum = arc
我正在用 C++11 编写一个函数,它采用 constant1 + constant2 形式的表达式并将它们折叠起来。 constant1 和 constant2 存储在 std::string 中,
我用 C++ 编写了这段代码,使用运算符重载对 2 个矩阵进行加法和乘法运算。当我执行代码时,它会在第 57 行和第 59 行产生错误,非法结构操作(两行都出现相同的错误)。请解释我的错误。提前致谢:
我是 C++ 的初学者,我想编写一个简单的程序来交换字符串中的两个字符。 例如;我们输入这个字符串:“EXAMPLE”,我们给它交换这两个字符:“E”和“A”,输出应该类似于“AXEMPLA”。 我在
我需要以下代码的帮助: 声明 3 个 double 类型变量,每个代表三角形的三个边中的一个。 提示用户为第一面输入一个值,然后 将用户的输入设置为您创建的代表三角形第一条边的变量。 将最后 2 个步
我是新来的,如果问题不好请见谅 任务:将给定矩阵旋转180度 输入: 1 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 输出: 16 15 14 13 12 11
我是一名优秀的程序员,十分优秀!