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

时间:2018-11-15 14:35:26

标签: c++ linker ld

我想通过交换代码来在一段代码中测试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;  
}

一个典型的学生密码,试图满足相同的规范, 进行测试。就我而言,是一个“主要”,几个#includes和“ using 命名空间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其他源代码中的内容。

谢谢 理查德

3 个答案:

答案 0 :(得分:0)

这在某种程度上违反了您的要求,但是我建议您更改学生代码的预期形式。不需要他们在单独的编译单元中对main进行编码,或随后要求对main进行编码,或者仅要求他们在提交之前重命名main来表示main_。或者,只需在提交后在编译之前将#define main main_添加到学生代码的顶部;对于简单的任务,就足够了。

之后,您无需从编译的代码中剥离任何内容。只需将所有您的函数放在namespace teacher上,编写自己的main即可完成所有需要的工作,并将所有代码链接在一起。更改并重新编译代码,以为函数调用teacher::f或为学生函数调用::f

答案 1 :(得分:0)

我认为唯一可能的解决方案是将其分为两个文件:

第一个文件对于教师和学生应该是通用的,并且可能同时包含mainfg的前向声明:

公用文件:(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(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的前向声明。

答案 2 :(得分:0)

这是从劳伦斯来的,回答了我的问题。我不能说便携性等。

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想法不起作用的评论现已删除。上面已经测试了几次。