[英]Selecting implementations of C++ functions using the linker
我想在一段代码中测试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++ -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
对学生的功能。
我认为唯一可行的解决方案是将其分为两个文件:
第一个文件对于老师和学生应该是通用的,并且可以包含g
main
和f
+ forward声明:
#include <iostream>
using namespace std;
int g(int x) ;
int f(int x) {
cout << "in teacher-f(" << x << ")" << endl;
return 46;
}
int main() {
cout << "in teacher-main()" << endl;
int x = 2;
int y = g(x);
cout << "g(" << x << ") returned " << y << endl;
}
第二个文件应该包含g
方法(+ f
前向声明):
#include <iostream>
using namespace std;
int f(int x);
int g(int x) {
cout << "in teacher-g(" << x << ")" << endl;
int y = f(x);
cout << "f(" << x << ") returned " << y << endl;
return 91;
}
#include <iostream>
using namespace std;
int f(int x);
int g(int x) {
cout << "in student-g(" << x << ")" << endl;
int y = f(x);
cout << "f(" << x << ") returned " << y << endl;
return 82;
}
现在你可以从common.cpp + teacher.cpp编译老师了
g++ -o teacher common.cpp teacher.cpp
和来自common.cpp + student.cpp的学生
g++ -o student common.cpp student.cpp
common.cpp甚至可以被静态库或共享库替换,你可以添加一个头而不是f
的前向声明。
这是来自劳伦斯并回答了我的问题。 关于便携性等我不能说
g++ -c student.cpp
g++ -c teacher.cpp
strip -N main student.o
objcopy -W _Z1fi student.o
objcopy -W _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(2) returned 82
谢谢!
PS我第一次尝试时必须写错字,否则剥离和弱化的顺序很重要......我的评论说这个objcopy -W想法不起作用现在已被删除。 以上已经过几次测试了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.