惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
S
Securelist
D
Docker
The Register - Security
The Register - Security
GbyAI
GbyAI
Recorded Future
Recorded Future
Engineering at Meta
Engineering at Meta
Stack Overflow Blog
Stack Overflow Blog
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
罗磊的独立博客
博客园 - 【当耐特】
F
Full Disclosure
WordPress大学
WordPress大学
腾讯CDC
小众软件
小众软件
大猫的无限游戏
大猫的无限游戏
D
DataBreaches.Net
SecWiki News
SecWiki News
L
Lohrmann on Cybersecurity
I
InfoQ
MyScale Blog
MyScale Blog
量子位
Cyberwarzone
Cyberwarzone
博客园 - 三生石上(FineUI控件)
The Hacker News
The Hacker News
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Jina AI
Jina AI
博客园_首页
H
Help Net Security
K
Kaspersky official blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Webroot Blog
Webroot Blog
Blog — PlanetScale
Blog — PlanetScale
V
Vulnerabilities – Threatpost
Y
Y Combinator Blog
The Cloudflare Blog
P
Proofpoint News Feed
V
Visual Studio Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tailwind CSS Blog
爱范儿
爱范儿
P
Privacy International News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
The GitHub Blog
The GitHub Blog
C
Cybersecurity and Infrastructure Security Agency CISA
B
Blog RSS Feed

博客园 - xlander

跟实际生活相关的饭否应用 5个跟实际生活相关的Twitter应用 Google Code上两个LPC21XX开源项目 Router牌音箱 基于ARM的网络收音机 博客程序换成了Z-Blog的 音箱?储钱罐? 显式指针转换的教训 使用结构体中成员变量指针的教训 结构体中位段、字节对齐并用的教训 日本某商场里的智能瀑布 ADS下C语言中局部变量的存储位置分配 救活TrackBack的偏方 近期几个开源的嵌入式产品 几个自制心电图的网络资源 哇哦级的贴片焊接教学视频 自动五线谱识别及音乐合成装置 简易指纹识别授权访问系统 PIC18F2550实现的基于HID的USB示波器
C语言的跨编译器编译
xlander · 2008-08-26 · via 博客园 - xlander

我有个项目,整个系统有若干软件组成,一个是嵌入式设备,在ARM Developer Suite(ADS)下用C语言开发,另外在PC(x86)平台上还有几个软件,在Visual C++下用C++开发,这几个软件需要相互通讯。对通讯数据的打包、解包是它们之间公用的代码。

尽管我也知道c++可以直接调用c语言,当时,为了图省事儿,我做了一个明知十分愚蠢却故意为之的决定,用版本管理的话来说,我在一个基础版本的基础上,分别定制了几个分支版本,这几个版本算法都是一致的,只是有关编译器语法的部分各自有些细微的差别。

就这样,我跳进了我自己挖的火坑里。每一次增加、修改算法,我都需要在另外的一个版本里,做差不多同样的工作。

就在几天前,忍无可忍的我,决定抽出专门的时间,对这部分代码大动干戈。

首先是语法部分。两个编译器有关字节对齐的指令是不同的,在VC下使用#pragma pack,在ADS下使用__packed关键字。

在VC下,是这样:

//时间变量
#pragma pack(push)
#pragma pack(1)
struct _tag_Time//时间
{
uint8 cSecond;
uint8 cMinute;
uint8 cHour;//24小时值
uint8 cDay;
uint8 cMonth;
uint8 cYear;
};
#pragma pack(pop)

在ADS下,是这样:

__packed struct _tag_Time//时间
{
uint8 cSecond;
uint8 cMinute;
uint8 cHour;//24小时值
uint8 cDay;
uint8 cMonth;
uint8 cYear;
};

为了区分编译环境是VC,还是ADS,我采用了VC编译器自定义的宏_MSC_VER。似乎#pragma pack不能放在#define宏中展开,只好折衷采用下面的办法。

#ifndef _MSC_VER
#define COMPLIER_ADS
#else
#define COMPLIER_VC
#endif
#ifdef COMPLIER_ADS
#definePACK_STRUCT_FIELD(x)__packed x
#definePACK_STRUCT_STRUCT
#definePACK_STRUCT_BEGIN__packed
#definePACK_STRUCT_END
#endif
#ifdef COMPLIER_VC
#definePACK_STRUCT_FIELD(x)
#definePACK_STRUCT_STRUCT
#definePACK_STRUCT_BEGIN
#definePACK_STRUCT_END
#endif
#ifdef COMPILER_VC
#pragma pack(push)
#pragma pack(1)
#endif
PACK_STRUCT_BEGIN
struct _tag_Time//时间
{
uint8 cSecond;
uint8 cMinute;
uint8 cHour;//24小时值
uint8 cDay;
uint8 cMonth;
uint8 cYear;
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
typedef struct _tag_Time TTime;
#ifdef COMPILER_VC
#pragma pack(pop)
#endif

修改这些跟编译器语法有关的内容后,代码在ADS和VC下都可以正常编译了。

接下来,在PC平台下,我有多个软件需要使用此代码,所以,将这部分代码抽取出来放在一个单独的工程里,供其它工程公用,做成静态链接库是比较合适的方法。

在这个过程中,碰到些小挫折,囫囵吞枣似的通过google解决掉,但是依然没弄懂其中的原理,留记之,怕日后又忘掉了。

碰到的两个错误是:

1、LNK2019: 无法解析的外部符号... ...

解决方法:

在声明函数的.h头文件中,使用extern "C"修饰函数。

#ifdef __cplusplus
extern "C" {
#endif
//函数声明
//....
#ifdef __cplusplus
}
#endif

另外,还要确认静态链接库工程的调用约定为__cdecl(默认)。设置方法:配置属性 -> C/C++ -> 高级 -> 调用约定。可能使用__stdcall可以供Delphi语言调用,但是我没有尝试成功。

2、LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) 已经在 libcmt.lib(typinfo.obj)

解决方法:

修改静态链接库工程的“运行时库”设置,与主工程保持一致。缺省值为“多线程DLL”或者“多线程调试DLL”,修改为“多线程”或者“多线程调试”。

设置方法:配置属性 -> C/C++ -> 代码生成 -> 运行时库。

在csdn论坛上,有高人指点我,可以使用制作针对不同平台的makefile,可能这是终极解决方案,但是我对makefile知之甚少,没有尝试。

Copyright © 2008

继续阅读《C语言的跨编译器编译》的全文内容...

分类: 软件开发 | Tags: 跨平台  ARM  C   | 添加评论(0)

相关文章: