脚本语言与c/c++库之间调用的原理是什么?

纳兰少
  • 87

不同语言之间的调用通信是很多的,以脚本语言调用c++为例,如果是两个独立不同的进程,那采用进程间通信的方式可以传递数据。
但如果是c++库呢?
比如nodejs底层就会调用c++模块,或者可以调用第三方c++库。调用方法也就是具体怎么操作我实验过,但是更底层的原理,比如nodejs到到底是怎么调用c++的,就不太清楚了,有能讨论或者解答一下的么?

回复
阅读 4.6k
5 个回答

上面的答案很多都是说的通俗表面的道理,但其实我是想知道一些底层调用的原理。最近看到一篇文章里的说法我觉得比较清楚
以python调用c库为例说明:

为了实现调用C函数,Python解释器需要做:

(1)找到函数所处的位置:这个意味着在C编译器编译成的二进制文件中寻找这个函数。
(2)在可执行的内存中,载入有关这个函数的相关代码。
(3)在调用这个函数前,将Python的参数转换为C兼容的参数。
(4)用正确的方式调用这个函数。
(5)将C函数的返回值转换成Python兼容的变量并将其返回至python代码中。


ref Glib GObject

Node.js调用C有两种方式。
一种方式是原生模块,这是常规方式。就是一个DLL库,编程的时候按照Node.js的约定,编写特定形式的接口函数,并include node.js的头文件,并和node.js提供的一些文件一起编译。这样的DLL会导出特定的函数。node.js动态加载DLL,通过特定的函数得到模块支持的方法,然后调用那些方法,传递的参数也是V8引擎定义的JS类对象。因为用了类,必须是C++编写,但是可以作为封装层,封装别的C库。Node.js自带的文件系统访问模块等都是这样的。
第二种方式就是第三方DLL。没有按照约定的方式编写,比如Windows的系统DLL。需要Node-FFI。FFI是一种跨语言调用技术,很多脚本语言都有自己的实现。原理就是根据代码中声明的C函数定义,动态生成机器指令,模拟C的函数压栈、弹栈过程。因为V8引擎正好是支持JIT即时编译的,所以很容易实现。这种方式缺点就是因为是没有编译器检查的,所以如果函数声明不对了,可能会导致程序崩溃。

你说的应该是脚本语言C++扩展开发的部分,你们可以找下相应的文章看看怎么写脚本语言的C++扩展。比如http://blog.csdn.net/yushulx/...

很简单,因为nodejs本身就是由c实现的,而c++是c的超集。其他语言类似。

所有的脚本语言都是有一个底层的另一个实现语言,用来把该语言翻译为机器语言。而去看一下各个脚本语言,基本都有一个底层的引擎,而现在牛人遍地,对不同的底层语言都有自己的坚持,大公司的业务场景也不一样,就会选择重写这些底层。如果从这样的角度讲,脚本语言的底层实现可以是任何C语言或者C++,java之类的都可以实现,只是效率会有差异,底层实现也确实有差异,不过有时候即使这样的底层变更了,但是之前写的代码有时候也不用改变就可以正常运行。说了这么多,其实就是他们都是遵循了一定的方式或者协议,来完成这些底层的构建。说出了这样的一个思想,可以从任何一种你会的语言去切入,google一下,那么就是学一个,会十个的进展。希望能帮到你,有什么可以随时回复我,互相交流哈。

你知道吗?

宣传栏