C语言与C++编译连接的不同点(从程序中看)
2016-11-25 14:45
281 查看
一:先上程序
a.h
a.c
b.h
b.c
main.c
Makefile(用C++编译程序)
此时编译连接有问题:
原来是编译的时候出了问题:
将上面的用C++编译连接改为用C编译连接,只需要将Makefile改为CC=gcc,此时没有问题:
原因是:
C语言中所有的函数不能同名,而C++中函数时可以同名的,当采用上述编程方式a.h中屏蔽了extern void DYNAMIC_SETUP(void);,虽然在语法上a.c中的DYNAMIC_SETUP();没有声明,但是采用C语言编译时,此时编译器会以默认的方式确认程序中已存在DYNAMIC_SETUP函数。而C++总不会采用默认的方式,直接查看是否声明,所以就产生错误。
若将上述的a.h中屏蔽的extern void DYNAMIC_SETUP(void),打开就没有任何语法问题了,怎样编译都对。
设计模式中的收获:
1.在有些动态库中,要想复用某些函数,可以使用宏定义函数指针的方式,在其它所有动态库中,只需要#define 具体函数 宏函数指针,即可,例如a.c和b.c中的应用。
2.若要是我要将程序编译成一个动态库,给使用者仅仅提供.h文件,对于.h文件中的数据结构类型无需考虑细节时,可以在.h文件中typedef struct _DYNAMIC *PDYNAMIC;,在相应的.c文件中进行struct _DYNAMIC的实现,如b.h和b.c。
3.对于我们要提供的动态库,只需要提供.h文件,此时.c文件中的所调用的函数或数据类型,对于我们的提供者是不需要知道的,但是,若.h文件中传参的时候必须使用.c中调用的数据类型,此时的做法是在提供的.h文件中单独的声明一下例如extern signed short CDBC_C_CHAR;,让其编译通过就行。而在.c文件中进行转换例如SQLSMALLINT CDBC_C_CHAR = SQL_C_CHAR;SQL_C_CHAR是我.c中实现所需要的调用动态库中的类型。
一:先上程序
a.h
#include <stdio.h> //extern void DYNAMIC_SETUP(void); void Init(void);
a.c
#include "a.h" void Init(void) { DYNAMIC_SETUP(); }
b.h
#include <stdio.h> #include <stdlib.h> typedef struct _DYNAMIC *PDYNAMIC; void SetUp(void); void FUN(PDYNAMIC pDynamic);
b.c
#include "b.h" struct _DYNAMIC { int nA; }; #define SetUp DYNAMIC_SETUP void SetUp(void) { printf("test-------OK\n"); PDYNAMIC pDynamic = (PDYNAMIC) malloc(sizeof(*pDynamic)); pDynamic->nA = 3; FUN(pDynamic); free(pDynamic); } void FUN( PDYNAMIC pDynamic) { printf("pDynamic->nA=%d\n", pDynamic->nA); }
main.c
#include <stdio.h> #include "a.h" int main() { printf("into main fun.........\n"); Init(); printf("out main fun.........\n"); return 0; }
Makefile(用C++编译程序)
APP = dynamic CC = g++ CFLAGS = -g SRCS = a.c b.c main.c $(APP):$(SRCS) $(CC) $(CFLAGS) $(SRCS) -o $(APP) clean: rm -rf *.o $(APP)
此时编译连接有问题:
原来是编译的时候出了问题:
将上面的用C++编译连接改为用C编译连接,只需要将Makefile改为CC=gcc,此时没有问题:
原因是:
C语言中所有的函数不能同名,而C++中函数时可以同名的,当采用上述编程方式a.h中屏蔽了extern void DYNAMIC_SETUP(void);,虽然在语法上a.c中的DYNAMIC_SETUP();没有声明,但是采用C语言编译时,此时编译器会以默认的方式确认程序中已存在DYNAMIC_SETUP函数。而C++总不会采用默认的方式,直接查看是否声明,所以就产生错误。
若将上述的a.h中屏蔽的extern void DYNAMIC_SETUP(void),打开就没有任何语法问题了,怎样编译都对。
设计模式中的收获:
1.在有些动态库中,要想复用某些函数,可以使用宏定义函数指针的方式,在其它所有动态库中,只需要#define 具体函数 宏函数指针,即可,例如a.c和b.c中的应用。
2.若要是我要将程序编译成一个动态库,给使用者仅仅提供.h文件,对于.h文件中的数据结构类型无需考虑细节时,可以在.h文件中typedef struct _DYNAMIC *PDYNAMIC;,在相应的.c文件中进行struct _DYNAMIC的实现,如b.h和b.c。
3.对于我们要提供的动态库,只需要提供.h文件,此时.c文件中的所调用的函数或数据类型,对于我们的提供者是不需要知道的,但是,若.h文件中传参的时候必须使用.c中调用的数据类型,此时的做法是在提供的.h文件中单独的声明一下例如extern signed short CDBC_C_CHAR;,让其编译通过就行。而在.c文件中进行转换例如SQLSMALLINT CDBC_C_CHAR = SQL_C_CHAR;SQL_C_CHAR是我.c中实现所需要的调用动态库中的类型。
相关文章推荐
- 一个程序在C语言和C++语言环境下得到不同结果
- [C/CPP系列知识] 那些程序C语言可以编译通过但C++无法编译成功 Write a C program that won’t compile in C++
- 怎么让C++的程序连接C编译出来的库?
- c/c++程序编译连接过程
- c/c++程序编译连接过程
- c/c++程序编译连接过程
- C++ 程序编译连接过程(VC)
- ubuntu使用技巧——如何编译C++和C语言的使用程序
- c/c++程序编译连接过程
- c/c++程序编译连接过程
- C++的编译单元、可执行程序、内部连接与外部连接
- linux下c程序c++程序混合编译,c程序中调用c++程序,c语言项目与c++语言项目的合并
- Linux下编写C++程序连接mysql数据库编译时指定头、库
- C#与C++对语句(i++ + i++)编译的不同
- C/C++编译的程序占用的内存分类
- 继续C++:gcc编译、连接和makefile的使用
- C语言与C++不同之函数定义
- 调整编译和连接参数去除目标程序中的无用代码
- 编写程序与做文章 ----- 致C语言初学者 付:C还是C++
- c与c++程序的不同对调试的影响