recan
recan
http://yyds.recan-li.cn 一个专注于嵌入式软件架构设计的新生代农名工

注册于 5 months ago

回答
169
文章
1
关注者
1

好文,先收藏了。
恰好最近刚好要把一个RISC-V架构的处理器移植要RTT上面,
看了楼主的文章,感觉思路又清晰了些,
后续有空再请教请教楼主。

先说下这个错误
../applications/main.c:54:15: warning: passing argument 1 of 'uart1_txd' from incompatible pointer type [-Wincompatible-pointer-types]

 uart1_txd(PREES2); 

核心含义就是,你传入的第1个参数与uart1_txd函数需要的参数不匹配;
为何不匹配:
你定义的 char *a[], 而你传入的是 char a[]。
再说一点,这个接口原型
int uart1_txd(char *uart1_trans[])
设计得不合理。
看你的实现,你就是想通过uart1发送一段buffer出去。
比较建议的函数原型:
int uart1_txd(char *uart1_trans, int len);
然后你调用的时候,就是
uart1_txd(PREES2, sizeof(PREES2));
接口设计成这样,第一个参数实则是一个指针,也可以理解成一个数组的起始地址,第二个参数指定这个指针指向内存的字节数,这个字节数由调用者绝对;而你现有的代码,这个长度8写在uart1_txd里面是不合适的。
一般设计带buffer处理的接口的传参,都是 char *p, int len这种写法,可以参考C库的一个接口你就明白了:
ssize_t write(int fd, const void *buf, size_t count);
image.png
以上答案,提供点思路,希望能够帮助到你。

跟进补充:
自己摸索了下,发现
手动在rtconfig.h中加上这个宏定义

#define HAVE_SYS_SELECT_H 1

就能编译过了。
感谢关注,结帖。

c文件要想调用到c++的接口,建议按照以下步骤进行:
1.编写你的c++类,做好代码实现,比如命名为a.cpp;
2.建议一个wrapper的c++文件,把c++类的方法转换成c接口;比如命名为wrapper.cpp;
注意wrapper里面的封装代码,要使用

ifdef __cplusplus

extern "C" {

endif

//wrapper source code

ifdef __cplusplus

}

endif

包起来,这样编译的时候才会按照c的接口形式编译;
同时导出wrapper的c接口到头文件中,也使用上面这个包起来。
3.建立你的c调用文件,调用wrapper导出的c接口;比如命名为test.c;
4.开始编译:使用g++编译a.cpp和wrapper.cpp,使用gcc编译test.c;
然后链接成可执行文件,同时包含c++的库。
这样就可以完成c调用c++了。
你可以试试看,希望能帮助到你。

下次如果再碰到类似
undefined reference to `xxx'
错误时,排查思路如下;
1.明确下,这个错误的根本原因是找不到xxx函数的实现;
2.查找下这个xxx函数是在哪个C文件定义实现的,如果有源码的,确保这个C文件参与了编译,最终有被链接;
3.如果这个xxx函数是在库里面实现,那么需要确认这个实现xxx函数的库文件,是否有被加入到链接列表里面。
注意一点:这个错误跟包不包含头文件没有直接的关系;处理头文件是在预编译阶段完成的,而这个错误是在链接阶段出现的。
希望答案,希望对你有帮助,谢谢。

出现这个 undefined referenced to xxx错误的根本原因
就是链接的过程中,找不到这个xxx函数的实现代码。
看这几个没有找到实现的函数都是c库的函数,看来时c库没链接到,或者c库是一个阉割过的。

回到
顶部

发布
问题

投诉
建议