Mac下编写lua的C模块

1.5k 词
<p>最近在研究lua下protobuf的使用,必然就会接触到了云风大侠的pbc,github上下了源码进行编译,发现想要把binding下面的测试代码运行起来,还是有一些坑点的。</p>

/binding/lua53 目录下有 Makefile pbc-lua53.c protobuf.lua test.lua几个主要的文档。

调用的层次大概是:test.lua会 require protobuf.lua 文档,它是对 pbc-lua53.c 导出的C函数库的一个封装,因此 protobuf.lua是真正 require C函数库的。Makefile 复杂将pbc-lua53.c 编译成动态链接库。

但是要注意Linux和Mac上编译选项的差异,直接在命令行下 make 会报错:

Undefined symbols for architecture x86_64:
  "_luaL_buffinit", referenced from:
      __pattern_pack in pbc-lua53-57d6af.o
  "_luaL_checkinteger", referenced from:
  ...

看到Undefined symbols的第一反应是没有链接lua的静态库嘛,于是顺手就修改Makefile文档,指定lua库的链接:

$(CC) $(CFLAGS) -shared -o $@ -llua -I../.. -I$(LUADIR) -L../../build $^ -lpbc

make一下,编译通过,运行lua test.lua却报错:

lua: multiple Lua VMs detected
stack traceback:
····

google一下,原因是我们编译protobuf.so动态链接库,静态链接了一次lua库,然后运行test.lua的时候,又动态链接了一次,导致multiple Lua VMs detected

正确的 Makefile修改方式,应该是:

C = gcc
CFLAGS = -O2 -fPIC -Wall -bundle -undefined dynamic_lookup
LUADIR = /usr/local/include
TARGET = protobuf.so

.PHONY : all clean

all : $(TARGET)

(TARGET) : pbc-lua53.c »···(CC) $(CFLAGS) -o @I../..I@ -I../.. -I(LUADIR) -L…/…/build $^ -lpbc

clean :
»···rm -f $(TARGET)

通过 -bundle -undefined dynamic_lookup 指定未找到的符号将在动态链接的时候,进行动态查找。同时删掉-shared 选项。

make然后lua test.lua结果如下:

test/addressbook.proto
tutorial
Profile
	nick_name [1] LABEL_OPTIONAL
	icon [2] LABEL_OPTIONAL
Person
	name [1] LABEL_REQUIRED
	id [2] LABEL_REQUIRED
	email [3] LABEL_OPTIONAL
	phone [4] LABEL_REPEATED
	test [5] LABEL_REPEATED
	profile [6] LABEL_OPTIONAL
Ext
AddressBook
	person [1] LABEL_REPEATED
Alice
12345
	1301234567	HOME
	87654321	WORK
Alice	123	table: 0x7feff8600950

测试的case正常跑通!