我需要在我的C程序中使用简单的ELF文件.我不能使用任何外部库,但我可以使用elf.h.
让我们把hello.o文件作为源代码:
int Hello() { return 3; }
Run Code Online (Sandbox Code Playgroud)
我怎样才能访问Hello只有hello.o文件的ohter C程序?
我应该把它加载到内存中使用mmap或者像这样.最后我需要使用更复杂的ELF文件,但我现在不知道,如何开始.
更新:我需要按照我描述的方式执行此操作,因为它是出于学习目的.整个问题比我描述的更复杂.
对于这个问题假设我需要编写方法:
int HelloFromElfO(const char* helloFile);
Run Code Online (Sandbox Code Playgroud)
这将执行Hello在中实现的功能helloFile.
我不想要完整的答案.我不需要任何代码.我需要一些东西开始.
我有关于ELF文件结构的基本知识,但我不知道如何在没有任何解析器的情况下使用二进制文件在C中工作或者像这样.
UPDATE2:好的,像readelf这样的应用程序非常复杂.所以也许我尝试这种方式:再说一遍,我已经hello.o映射到内存了ptr.如何获得指向Hello函数的指针?
如何从中获取任何结构化数据hello.o?我的意思是,不是纯字节,而是我可以使用的东西.
我正在构建一个微型微控制器,其中只包含用于自学目的的基本要素.通过这种方式,我可以刷新我对linkerscript,启动代码等主题的了解......
编辑:
我收到了很多评论,指出下面显示的"绝对最小STM32应用"并不好.当你注意到向量表不完整,.bss-section没有处理,外围地址不完整时,你是完全正确的,...请允许我解释原因.
作者的目的从未在本章中编写完整且有用的应用程序.他的目的是逐步解释链接器如何工作,启动代码如何工作,STM32的启动过程是什么样的,......纯粹用于教育目的.我可以欣赏这种方法,并学到了很多东西.
我在下面的例子取自相关章节的中间部分.本章继续向linkerscript和启动代码添加更多部分(例如初始化.bss-section).
我从他的章节中间放置文件的原因是因为我遇到了特定的错误消息.我想在继续之前解决这个问题.
有问题的章节在他书的最后.它适用于想要获得更多人们甚至不考虑的主题的更有经验或好奇的读者(大多数人使用制造商给出的标准linkerscript和启动代码而不读它).
请记住这一点,请让我们关注手头的技术问题(如下面的错误消息中所述).也请接受我真诚的道歉,我之前没有澄清作者的意图.但我现在已经完成了,所以我们可以继续前进;-)
我正在阅读的教程是本书的第20章:"掌握STM32"(https://leanpub.com/mastering-stm32).该书解释了如何使用两个文件制作一个微型微控制器应用程序:main.c和linkerscript.ld.由于我没有使用IDE(如Eclipse),我还添加build.bat并clean.bat生成编译命令.所以我的项目文件夹看起来像这样:
在继续之前,我应该提供一些关于我的系统的更多细节:
操作系统: Windows 10,64位
微控制器:带STM32F401RE微控制器的NUCLEO-F401RE板.
编译器: arm-none-eabi-gcc版本6.3.1 20170620(发布)[ARM/embedded-6-branch revision 249437].
主文件如下所示:
/* ------------------------------------------------------------ */
/* Minimal application */
/* for NUCLEO-F401RE */
/* ------------------------------------------------------------ */
typedef unsigned long uint32_t;
/* Memory and peripheral start addresses (common to all STM32 MCUs) */
#define FLASH_BASE 0x08000000
#define SRAM_BASE 0x20000000
#define PERIPH_BASE 0x40000000
/* …Run Code Online (Sandbox Code Playgroud) 我正在尝试数组指针和函数指针的一些随机声明。我被打中了。
#include<bits/stdc++.h>
int add(int a,int b){
return 1729; }
int main(){
int (abc)(int,int);
abc = add;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
发出的错误是:
#include<bits/stdc++.h>
int add(int a,int b){
return 1729; }
int main(){
int (abc)(int,int);
abc = add;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但随着这两个abc和add是同一类型的,它为什么要转变?还是可以将函数分配给新变量?如果是这样,该怎么做?
我正在使用dlib(无关紧要;实现我建模的贝叶斯网络,以便在复杂域中处理概率).
我在其中一个示例程序中遇到了以下内容:
cout << "p(D=0) = " << solution.probability(D)(0) << endl;
在C++中调用函数后,我从未见过双括号.它做什么以及如何工作?
假设我有函数foo_1(),foo_2(),... foo_n()
我怎么能用一个循环来调用它们,就是如何将一个字符串"转换"为一个函数调用:
for (i = 0; i < n; i++)
switch (fork()) {
case 0: //child process
*COMVAR+=m;
//call foo_i()
exit(4);
case -1:
exit(5);
}
Run Code Online (Sandbox Code Playgroud) 我对此主题有些困惑。我知道什么是回调,但是函数指针让我更加困惑。它们是否可以表示同一件事(至少在C / C ++上下文中)?还是其中之一包括其他功能,例如函数指针可用作回调,反之亦然。
函数指针和回调之间是否存在关系,或者它们是完全不同的主题?
在一个项目中,我遇到了以下代码行。
::std::unordered_map<std::string, Channel*(*)(Module*, const Parameters&)>;
Run Code Online (Sandbox Code Playgroud)
有人知道 Channel*(*) 是什么意思吗?和Channel**一样吗?这对我来说似乎令人困惑和过于复杂。
Channel 构造函数如下所示:
Channel(Module* module, const util::Parameters& parameters);
Run Code Online (Sandbox Code Playgroud) 有人可以向我解释一下这个程序吗
#include <stdio.h>
void print(void)
{
printf("g");
}
int main()
{
void(*message)(void);
print(); // i have doubt here it g
message = print; // now here why it is printin g again
(*message)();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个程序void首先带来了一个函数,现在printf当我们进入main函数时,第一行指示指针消息,该消息为空,之后没有得到原因
我不确定用什么术语来正确解释这一点,但我已将代码单独放入一个文件中,以了解它是如何工作的,我希望有人可以进一步帮助我!
我理解的主要问题是为什么它void (*exec)(struct test_t*);确实有效?结构成员将自身转换为结构指针?这让我很困惑。
另外,在 switch-case 语句中,我理解在这些行中test.exec = fcn1; test.exec(&test);函数被分配给该结构成员,并且在括号中传递函数参数以便执行该函数。但是这个设置在变量定义中是如何实际发生的呢?
我基本上是分配一个函数作为结构成员吗?如果是,那么在编译结构之前它如何了解自身?这个语法是(*x)(struct y*)用来做什么的?
typedef struct test_t{
int num;
void (*exec)(struct test_t*);
}test_t;
void fcn0(test_t* test);
void fcn1(test_t* test);
void fcn2(test_t* test);
int main(){
while(1){
test_t test = {
.num = 0,
.exec = fcn0
};
printf("Enter a number: ");
scanf("%d", &test.num);
switch (test.num)
{
case 1:
test.exec = fcn1;
test.exec(&test);
break;
case 2:
test.exec = fcn2;
test.exec(&test);
break;
default:
test.exec = fcn0;
test.exec(&test);
break;
} …Run Code Online (Sandbox Code Playgroud)