c++ - 使用链接器选择 C++ 函数的实现
问题描述
我想在一段代码中测试 C++ 函数,方法是将它们一个一个地交换为已知在工作上下文中工作的函数,其中交换是使用链接器完成的。(我在 linux 下使用 C++ 和 GCC。)不幸的是,我对如何驱动链接器知之甚少,不知道如何做到这一点,或者即使它是可能的。
对我来说,主要原因是根据教师的模型解决方案测试学生的代码,尽管我可以想象很多其他情况可能会对这种方法感兴趣。请注意,学生的源代码是可用的,可以以我喜欢的任何方式编译,但不能编辑此源代码。但是,教师的代码可以根据需要进行修改。
下面是一个简单的例子来说明这个想法。
这是老师的代码,其中函数可以以类似于所示的方式相互调用。这里的所有功能都假定完全符合它们的规格。
#include <iostream>
using namespace std;
// model teacher program : main calls g which calls f
int f(int x) {
cout << "in teacher-f(" << x << ")" << endl;
return 46;
}
int g(int x) {
cout << "in teacher-g(" << x << ")" << endl;
int y = f(x);
cout << "f(" << x << ") returned " << y << endl;
return 91;
}
int main() {
cout << "in teacher-main()" << endl;
int x = 2;
int y = g(x);
cout << "g(" << x << ") returned " << y << endl;
}
一个典型的学生代码,试图满足相同的规范,被测试。在我的例子中,一个“main”、几个#includes 和“using namespace std;” 将是预期的。
#include <iostream>
using namespace std;
// model student program : main calls g which calls f
int f(int x) {
cout << "in student-f(" << x << ")" << endl;
return 27;
}
int g(int x) {
cout << "in student-g(" << x << ")" << endl;
int y = f(x);
cout << "f(" << x << ") returned " << y << endl;
return 82;
}
int main() {
cout << "in student-main()" << endl;
int x = 4;
int y = g(x);
cout << "g(" << x << ") returned " << y << endl;
return 0;
}
我想一一交换每个老师的功能,以单独测试每个学生的功能。
这是一次尝试,在这种情况下测试学生的 g()
g++ -c student.cpp
# (this makes student.o)
# strip f() and main() from student.o:
strip -N main -N _Z1fi student.o
# similarly for teacher, but stripping g
g++ -c teacher.cpp
strip -N _Z1gi teacher.o
g++ -o final teacher.o student.o
./final
我期望的结果是
in teacher-main()
in student-g(2)
in teacher-f(2)
f(2) returned 46
g(4) returned 82
不幸的是,我得到:
strip: not stripping symbol `_Z1fi' because it is named in a relocation
我尝试用 .so 库做类似的事情。删除的错误消息消失了,但不幸的是这次老师主要调用了我试图删除的老师 g。
g++ -shared -fPIC -o student.so student.cpp
g++ -shared -fPIC -o teacher.so teacher.cpp
strip -N main -N _Z1fi student.so
strip -N _Z1gi teacher.so
g++ -o final teacher.so student.so
./final
给予
in teacher-main()
in teacher-g(2)
in teacher-f(2)
f(2) returned 46
g(2) returned 91
有什么建议么?这甚至可能吗?如果没有,有没有办法做同样的事情?如前所述,我无法编辑 student.cpp,但我可以从其他源代码中#include 它。
谢谢理查德
解决方案
这有点违反您的要求,但我建议您更改学生代码的预期形式。不要要求他们编码main
,或者要求他们在单独的编译单元中编码,或者只是要求main
他们在提交之前重命名。或者只是在编译前提交后添加到学生代码的顶部;对于简单的任务,这就足够了。main
main_
#define main main_
之后,您不需要从已编译的代码中删除任何内容。只需将所有函数放入,编写自己的函数来完成所有需要的工作,然后将所有代码链接在一起。更改并重新编译您的代码以调用您的函数或学生的函数。namespace teacher
main
teacher::f
::f
推荐阅读
- html - 布局页面和视图冲突 MVC5
- c - 更新到 MacOs Mojave 10.14 后的 OpenGL 黑屏和 Gamma 校正?
- excel - 查找范围内符合特定条件的所有值并返回每一行 VBA
- create-react-app - 如何在 Create-React-App 2 中更改 PWA 工作箱缓存策略
- javascript - 如何替换字符串中的 \n 换行符,以便
标签可以显示新行
- javascript - 通过用户输入和 Javascript 更改特定表格单元格中的文本
- json - 杰克逊将对象序列化为地图的键
- c# - 在文本框数据网格视图单元格中添加新行 [C#]
- python - 为什么 Django 想用代理模型改变表?
- python - AcUro 使用 Python 和 OpenCV 提供的边角优化方法 CORNER_REFINE_SUBPIX