baifeng 发表于 2010-12-26 14:34:24

ads中有关cpp文件分散加载文件的问题

自己一个工程,大多数程序都是用C写的,显示部分一些功能想用C++写,因为考虑其封装和安全性都较好,也方便维护。在c文件中想调用c++的结果。

做法:cpp文件中提供c形式的接口函数:
extern "C" int foo(int a)
{
   // ....
   CMyclass my;
   return (my.output(a));
}

同时本cpp文件中提供CMyclass的类定义、实现部分。

在c文件中:
extern int foo(int);
c_result = foo(a);


使用ads,axd工具链开发、调试,c用armcc编译,cpp文件用armcpp编译.
2个文件各自的编译都已经正确,但是最终提示在连接时有问题,大约是说某个和堆栈相关的.o文件中的符号Image$$ZI$$Limit没有定义;
基本可以定位是因为cpp文件中定义的类出现的问题。

哪位有相关经验?可以告知应该如何写该工程的连接脚本(分散加载文件,scatter文件)?
c++的构造、析构函数是否需要单独分配section? 还是因为堆栈使用和c不同?
看了一些linux中.lds文件的写法,因为时间关系没有看太明白,大约是用了ctors和dtors之类的section.
谁能给个比较系统、全面的讲解?说说c++工程和c工程在连接方面的区别?

谢谢了!

baifeng 发表于 2010-12-27 09:10:10

有人能提供这个问题的解决方案吗?急!

baifeng 发表于 2010-12-28 13:58:37

有了一点点线索:
连接时会提示sys_stackheap.o未引用Image$$ZI$$Limit;
Image$$ZI$$Limit这个变量和__user_initial_stackheap相关;
sys_stackheap.o应该和ads自带库相关,在连接时引用(但未找到此文件,也未见到何处编译之);
如果不使用ads提供的armlib和cpplib库,需要重写__user_initial_stackheap()这个函数来初始化堆、栈指针位置(参见官方文档《库与浮点参考指南》)。

但是,我仅仅用了一个非全局的类,就和堆栈相关吗?(c语言环境已自己处理了堆栈问题)

baifeng 发表于 2010-12-29 10:54:45

唉,没有人回答。

不过自己找到了一个解决方法:
遍寻官方文档,发现和Image$$ZI$$Limit相关的只有__user_initial_stackheap一处;
于是写了一个空的__user_initial_stackheap(),问题就解决了。

分析:
1. 虽然c程序部分已经做了堆栈初始化(分别用不同文件定义堆栈底/顶变量,scatter文件定义堆栈位置。参见example代码中embeded目录样例),但是c++的构造函数和析构函数依然用了系统sys_stackheap.o的接口(和堆栈相关),其可能直接/间接调用了__user_initial_stackheap(类似于c语言__main中做的工作);
2. 观察cpp文件的汇编,发现构造函数中有bl operator new,析构函数中有bl operator delete,估计和上述堆栈管理也有关;
3. 这个问题在编译时不报错,仅连接时报错;
4. 观察cpp文件生成的目标文件.o,其符号表中有Lib$$Request$$armlib和Lib$$Requist$$cpplib符号,应该和armlink连接时选项-scanlib及cpp文件中使用的c++特性的东西有关。

quanguoheme 发表于 2011-1-4 13:36:23

Image$$ZI$$Limit 是ads编译后, 未初始化变量最后一个字节的地址
问一下, ads的官网在哪里,   
我装了ads,然后点help ——》manul 是个错误提示, 得不到ads的文档, 请问你有吗,
有的话,加我qq, 我

quanguoheme 发表于 2011-1-4 13:36:43

我的qq是:317298937

quanguoheme 发表于 2011-1-4 13:40:19

Image$$ZI$$Limit 是ads编译后, 未初始化变量最后一个字节的地址
是ads提供的一个符号, 只要在程序中这样:
              IMPORT        |Image$$RO$$Limit|
              IMPORT        |Image$$RW$$Base|   
              IMPORT        |Image$$ZI$$Base|   
      IMPORT        |Image$$ZI$$Limit|

就可以得到编译后的程序,zi段起始地址和结束地址

问一下楼主, 怎么在ads查看,c编译后产生的汇编代码

baifeng 发表于 2011-1-5 00:49:09

回复【6楼】quanguoheme
-----------------------------------------------------------------------

官网文档:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/index.html

在ads查看,c编译后产生的汇编代码:
在AXD中仿真时,源码处,右键菜单-->intersource。

或者用armcc的--asm参数生成汇编。
或者产生axf后,用fromelf查看帮助,有选项可以生成反汇编,重定向到文件可读。
页: [1]
查看完整版本: ads中有关cpp文件分散加载文件的问题