繁体   English   中英

使用链接器选择C ++函数的实现

[英]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 mainf + forward声明:

常用文件:(common.cpp)

#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前向声明):

老师(teacher.cpp):

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

学生(student.cpp):

#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM