写C的时候需要调用之前的一个C程序,想用动态链接库的方式。Mac下的动态链接库是dylib,与Linux下的.os或Windows下的.dll不同。由于之前没有接触过,所以翻了大量的博客,然而在编译过程中一路error。。。还是没能解决问题。最后看了苹果官方的关于动态链接库的介绍https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/000-Introduction/Introduction.html#//apple_ref/doc/uid/TP40001908-SW1,终于顺利通过了。原文是英文文档,建议大家看看,不想看的也可以看我的博客内容。

下面简要说一下我的具体做法。

C生成动态链接库

假设你之前有一个function.c,我们现在需要调用它,先把它做成一个动态链接库。我是直接把这里面的main函数改了一下名字为enmain:

/*file: function.c*/
......
void enmain() {
fun1();
fun2();
...
}

在与function.c的同目录下新建一个function.h文件,里面就是对你要调用的函数的申明。因为我是需要调用function整个程序,所以只要申明enmain这个函数部分:

/*file: function.h*/
void enmain();

这时候.h文件就写好了,我们需要回过来对之前的function.c文件做一些修改补充:

  • 头文件加上
/*file: function.c*/
#include"function.h" //注意是用引号
#define EXPORT __attribute__((visibility("default"))) //具体原因可以看苹果官方的解释,我上面有贴链接
  • 在需要调用的函数前面加一行EXPORT
    /*file: function.c*/
EXPORT
void enmain() {
fun1();
fun2();
...
}

都修改好后,我们开始编译。在终端输入如下语句:

clang -dynamiclib -std=gnu99 function.c -current_version 1.0 -compatibility_version 1.0 -fvisibility=hidden -o libfunction.A.dylib

然后在与function.c的同目录下会出现一个libfunction.A.dylib。至此,动态链接库已经生成完毕。

C调用动态链接库

假设我写了一个程序test.c需要调用刚刚的function动态链接库。由于我这个例子里面只导出了一个函数就是enmain(),实际操作的时候,可以导出.c文件中的多个函数。

  • 头文件加上
    /*file: test.c*/
#include"function.h"
  • 在需要用到enmain()的时候,就像标准库函数一样正常使用:
    /*file: test.c*/
enmain();

然后编译:

clang test.c libfunction.A.dylib -o test

运行:

./test

注意

之前我写的function是.cpp文件,在将其编译为dylib时出现错误:

error: invalid argument '-std=gnu99' not allowed with 'C++/ObjC++'

所以后来改写为纯C就通过了。现在还不知道C++应该如何。。。

Mac下将C程序创建为动态链接库再由另一个C程序调用的更多相关文章

  1. mac下普通用户无法创建crontab的问题解决

    想在mac下弄一个crontab定时任务,以为会像linux上那样顺利那,结果碰壁了,报错信息例如以下: ➜  autoshell  crontab -ecrontab: no crontab for ...

  2. Mac下maven工程的创建,并搭建SSH环境

    最近项目有用到maven,就特地学了一下.maven的一句话攻略就是,项目托管.帮你解决各种项目琐事:清理,导包....等等. 首先先到apach官网去下载一个maven的包,http://maven ...

  3. [如何在Mac下使用gulp] 1.创建项目及安装gulp

    1.创建项目 2.安装gulp 3.创建gulpfile.js文件 4.运行gulp 创建项目 -创建项目文件夹命名为firstGulp,并在firstGulp目录下运行 npm init .npm ...

  4. 用C#给程序加启动画面并只允许一个应用程序实例运行

    . 启动画面类: public class SplashForm : System.Windows.Forms.Form { private System.Windows.Forms.PictureB ...

  5. Java笔记:编写第一个Java程序

    2017.6.17 1.编写第一个Java程序 创建text文本,命名第一个Java程序.txt 在里面编写Java代码 public class Demo1{ public static void ...

  6. mac 下基于firebreath 开发多浏览器支持的浏览器插件

    mac 下基于firebreath 开发多浏览器支持的浏览器插件 首先要区分什么是浏览器扩展和浏览器插件;插件可以像本地程序一样做的更多 一. 关于 firebreath http://www.fir ...

  7. Mac下Android配置及unity3d的导出Android

    昨晚实在弄的太晚了,费尽脑汁才弄出来. ok,关于mac下的eclipse的安卓配置,我仅仅贴一个网址,就ok了 http://developer.android.com/sdk/index.html ...

  8. OD学习笔记10:一个VB程序的加密和解密思路

    前边,我们的例子中既有VC++开发的程序,也有Delphi开发的程序,今天我们给大家分析一个VB程序的加密和解密思路. Virtual BASIC是由早期DOS时代的BASIC语言发展而来的可视化编程 ...

  9. 编译:一个 C 程序的艺术之旅(转载)

    C 程序为什么要编译才能执行?一个 C 程序在变成可执行文件的过程中,为什么要经过预处理.编译.汇编.链接这四道工序?让我们从这段简单的 C 程序开始. 为什么要编译 这并不是一个简单的问题.我们知道 ...

随机推荐

  1. 学习JQuery - 10

    第四章 Styling and Animating 1. 使用内联属性修改CSS 我们知道HTML在onload时会读取css的各项值. 那么,我们能不能在之后的操作中改变css值呢? 答案是肯定的! ...

  2. POJ 3122 Pie

    题目大意: 给出n个pie的直径,有f+1个人,如果给每人分的大小相同(形状可以不同),每个人可以分多少.要求是分出来的每一份必须出自同一个pie,也就是说当pie大小为3,2,1,只能分出两个大小为 ...

  3. vux版本升级

    一开始用的笨办法, 先卸载npm uninstall vux --save; 然后在安装npm install vux --save;  卸载的还是蛮快的,安装是在下班的时候,让电脑待机2个小时,第二 ...

  4. 【BZOJ4428】[Nwerc2015]Debugging调试 记忆化搜索+分块

    [BZOJ4428][Nwerc2015]Debugging调试 Description 你看中的调试器将不会在这件事上帮助你.有代码可以通过多种方式在调试与正式发布的间隙发生不同的行为,当出现这种情 ...

  5. Intellij IDEA同时打开多个项目

    extends:http://www.kaifazhe.me/java/99.html 使用eclipse习惯的同学知道是可以同时多个项目查看的,只需要import就可以了,但Intellij IDE ...

  6. Yii2中省市三级联动(栏目联动)

    先从表的设计开始: 表的结构: CREATE TABLE `global_region` ( `region_id` smallint(5) unsigned NOT NULL AUTO_INCREM ...

  7. jq简单城市二级联动实现

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. os模块os.walk() 方法和os.path.join()的简单使用

    os.walk:   http://www.runoob.com/python/os-walk.html os.path.join:   https://blog.csdn.net/zmdzbzbhs ...

  9. 对django框架架构和request/response处理流程的分析

    一. 处理过程的核心概念 如下图所示django的总览图,整体上把握以下django的组成: 核心在于中间件middleware,django所有的请求.返回都由中间件来完成. 中间件,就是处理HTT ...

  10. django-models的get与filter

    为了说明它们两者的区别定义2个models class Student(models.Model):name = models.CharField('姓名', max_length=20, defau ...