C/C++语言中,如何在main.cpp中调用另一个.c文件主要有5种思路:

  1、在VS2012 IDE中,将被引用的.c文件后缀名全部修改为.h,然后通过IDE的解决方案资源管理器中鼠标右键单击“头文件”-"添加"-“现有项”,选中修改后缀名后的.h文件-"添加",将待引用的文件添加到工程中。

  添加到“头文件”而不是“源文件”的作用:主要是使头文件的项类型属性为“C/C++ 标头”,而不是“C/C++ 编译器”。后者是将该文件独立编译成目标文件*.obj。用户可右键单击某个.h文件-属性-配置属性-常规-项类型,来查看。

  接着在main.cpp文件中,包含所需要使用头文件:

#include "13lman.h"

  然后在需要的地方,直接调用该函数即可,如下:

js=lman(3,1,200,f,q,r,h,y,x,p,g);

  2、不用修改文件扩展名,直接将待引用的.c文件添加到“源文件”下面,按照1的步骤将待引用的文件的"项类型“修改为“C/C++ 标头”。该方法的本质是将*.c文件当做*.h使用。如下图所示:

  

  接着在main.cpp文件中,包含所需要使用.c文件:

#include "13lman.c"

  然后在需要的地方,直接调用该函数即可,如下:

js=lman(3,1,200,f,q,r,h,y,x,p,g);

   3、首先,在IDE中右键选中头文件-添加-新建项-Visual C++-头文件(.h)-输入文件名,创建新的.h文件。如下图所示:

  接着,在function.h文件来声明这些待调用的函数:

#ifndef __FUNCTION_H__
#define __FUNCTION_H__
  int rinv(double a[],int n);
int lman(int n,int m,int k,double f[],double q[],double r[],double h[],double y[],double x[],double p[],double g[]);
#endif

  然后,按照2中的步骤,将待引用的.c文件添加到源文件节点下面。将其项类型设置为“C/C++ 编译器”,预编译头设置为“不使用预编译头”。如下图所示:

  接下来,在待引用的.c文件中包含function.h头文件(貌似这一步不用也可以编译-链接-运行成功???):

#include "function.h"

  紧接着,在主调用文件main.cpp中,文件中包含待引用的.c文件:

#include "13lman.c"

  最后,在需要的直接调用该函数即可,如下:

js=lman(,,,f,q,r,h,y,x,p,g);

  4、如果main.cpp需要调用的.c文件还需要依赖其它.c文件,则可以按照下图所示的方法设置各个文件的编译属性:

  前提是:所有的.c文件添加到“源文件”节点下面,将其项类型设置为“C/C++ 编译器”,预编译头设置为“不使用预编译头”(除了最后一个.c文件)。

  接着,在主调用文件main.cpp中,文件中包含待引用的.c文件:

#include "13lman.c"

  然后,在13lman.c文件中包含所依赖的4rinv.c文件:

#include "4rinv.c"

  最后,在需要的直接调用该函数即可,如下:

js=lman(,,,f,q,r,h,y,x,p,g);

  5、 所有的.c文件添加到“源文件”节点下面,将其项类型设置为“C/C++ 编译器”,预编译头设置为“不使用预编译头”。如果直接编译-链接会输出“error LNK2019: 无法解析的外部符号”链接错误。

  问题原因:C语言和C++语言混编,因为C++支持函数重载所以C++编译器生成的库文件中的函数名会面目全非,例如C编译器会生成 _readRegmark 这个函数名,而C++编译器则生成了"void __cdecl readRegmark(char *)" (?readRegmark@@YAXPAD@Z)这么个函数名。当你的函数是用C语言写的,VS编译器会按C语言规则编译,但链接器却不知道还傻傻的用C++规则的函数名去找,当然就找不到了。

  解决办法:在C语言的头文件或主动调用的main.cpp文件的最开始部分加入如下代码:

#ifdef __cplusplus
extern "C" {
#endif
void readRegmark(char *regmark); //这里写函数声明
#ifdef __cplusplus
}
#endif

  或者,更简洁一些:

extern "C"
{
int lman(int n,int m,int k,double f[],double q[],double r[],double h[],double y[],double x[],double p[],double g[]);
}

  这样的话就可以编译-链接成功了。上面的解决办法适用于待调用的.c文件中的函数还依赖于其他文件中的其它函数的情况。如果主动调用文件main.cpp还需要使用其它.c文件的函数,也可以用同样的方法解决。推荐使用第一种方法。因为第一种方法既能够让.cpp文件能够包含这个.c文件,又能让其它.c文件能够包含这个.c文件。需要注意的是:__cplusplus是C++编译器内置的宏。

  对OpenGL比较熟悉的用户可能会发现在OpenGL的头文件GL.h中的开头和结尾部分就使用了上面的用法,如下图所示:

            开头部分                                                                                         结尾部分

                              

参考链接:

1、同一个C语言工程不同C文件之间的函数互相调用问题(一)同一个C语言工程不同C文件之间的函数互相调用问题(二)同一个C语言工程不同C文件之间的函数互相调用问题(三)

2、C语言一个源文件如何调用另一个源文件里的函数

3、C语言为什么无法include另一个源代码文件

4、cpp到obj再到exe,重定义的问题

5、C/C++不同文件夹下包含头文件的方法及#include的使用

6、“error LNK2019: 无法解析的外部符号”之分析

7、碰到“error LNK2019: 无法解析的外部符号”

8、3.C++和C混合编程

[原创]C/C++语言中,如何在main.c或main.cpp中调用另一个.c文件的更多相关文章

  1. Java语言中:float、double数据类型在内存中是如何存储的

    引用参考 https://www.cnblogs.com/chenmingjun/p/8415464.html#4291528 https://blog.csdn.net/yansmile1/arti ...

  2. 如何在Sqlserver2000查询分析器中,,在一个库中调用另一个数据库中的数据表

    同一服務器 use aa select * from pubs.dbo.jobs 不同服務器 select * from openrowset('sqloledb','IP地址';'sa';'密碼', ...

  3. C语言中main函数的参数argc和argv

    参考资料: http://wiki.opencv.org.cn/index.php/Main%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0argc%EF%BC%8Cargv% ...

  4. c语言中的main函数讨论

    **从刚开始写C程序,相比大家便开始写main()了.虽然无数的教科书和老师告诉我们main是程序的入口.那么main函数是怎么被调用的,怎么传入参数,返回的内容到哪里了,返回的内容是什么?接下来我们 ...

  5. C语言中的main函数以及main函数是如何被调用的

    main函数是C语言中比较特殊的函数,C程序总是从main函数开始执行,main函数的原型是: int main(int argc, char *argv[]); 其中argc是命令行参数的个数,ar ...

  6. c语言中time相关函数

    工作中遇到的函数: int seed = time(NULL); srand(seed); signal(SIGINT, stop); signal(SIGUSR1, sig_usr1); 搜time ...

  7. Go 语言中,有时 nil 并不是一个 nil

    今天,我遇到了一个 Go FAQ.首先,作为一个小小的 Go 语言测验,看看您是否在 Go playground 中运行该程序之前就能推断出它应该打印出的内容(我已经将程序放在侧边栏中,以防它在 Go ...

  8. 在 Go 语言中,我为什么使用接口

    强调一下是我个人的见解以及接口在 Go 语言中的意义. 如果您写代码已经有了一段时间,我可能不需要过多解释接口所带来的好处,但是在深入探讨 Go 语言中的接口前,我想花一两分钟先来简单介绍一下接口. ...

  9. C语言中,头文件和源文件的关系(转)

    简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...

随机推荐

  1. Redis 学习资料目录(Important)

    redis学习路线: 以下是整理的学习redis优秀博客和优秀网站 一.原理: 1. redis命令在线操作 http://try.redis.io/ 2. 中文命令解释: Redis 命令参考 - ...

  2. 0<Double.MIN_VALUE

    好吧, 吐嘈一下: 前几天写代码时发现 Double 有几个静态成员变量, 如 MAX_VALUE , MIN_VALUE 等, 当时就自己"故名思意"了, 分别当成了 doubl ...

  3. CF 827E Rusty String FFT

    传送门 如果没有碍事的?的话,判定字符串的循环节直接用KMP的失配数组就可以搞定.现在有了碍事的?,我们就需要考虑更通用的算法. 考虑KMP失配数组判定字符串循环节的本质,发现判定\(k\)是否为字符 ...

  4. HTML存储详解

    和大家一起先来了解一下H5之前的存储方式: cookies的诞生: http请求头上带着数据 大小只能为4K 主Domain的污染 下面是百度的一些Cookies HTTP中带√的表示,只能被服务器端 ...

  5. Pig安装与应用

    1.  参考说明 参考文档: http://pig.apache.org/docs/r0.17.0/start.html#build 2.  安装环境说明 2.1.  环境说明 CentOS7.4+ ...

  6. ARDUINO 积木式编辑器整理

    原文地址:https://blog.everlearn.tw/arduino/arduino-%E7%A9%8D%E6%9C%A8%E5%BC%8F%E7%B7%A8%E8%BC%AF%E5%99%A ...

  7. SqlServer查询存储过程中包含指定的内容

    存储过程太多,有时只记得存储过程里面的某一点类容,想要找到对应的存储过程: SELECT obj.Name 存储过程名, sc.TEXT 存储过程内容 FROM syscomments sc INNE ...

  8. .net 下使用Quartz.Net

    Quartz.net是作业调度框架 1. 项目中添加quartz.net的引用(这里使用nuget管理) 新建一个类TimingJob,该类主要用于实现任务逻辑 using Quartz; using ...

  9. python下载指定的版本包

    首先我们很多时候在执行pip的时候是不行的  有时候很难成功,这个时候我们就要想其他的版本了 一.是不是这个包需要指定版本, 比如python2的和mysql链接的是,而python3则是mysqlc ...

  10. 使用AKLocationManager定位

    使用AKLocationManager定位 https://github.com/ideaismobile/AKLocationManager 以下是使用情况: 是不是很简单呢,我们可以将它的步骤进一 ...