我一直在尝试 Perl XS C API,但遇到了障碍。
我在下面简化了我的示例。假设现有结构 MyObject 然后访问属性“a”或“b”并为其中之一创建哈希,我可以使用以下代码:
typedef struct {
const char *prop_a;
const char *prop_b;
struct {
const char **items;
int num;
} names;
} MyObjectInfo;
typedef MyObjectInfo *MyObject;
MODULE = my_obj PACKAGE = MyObject PREFIX = my_obj_
SV *
my_obj_a(o)
MyObject o
CODE:
SV *info = newHV();
hv_store(info, “a”, 1, newSVpvn(o->prop_a, strlen(o->prop_a)), 0);
int i;
for(i = 0; i < o->names.num; i++) {
const char *n = o->names.items[i];
hv_store(info, n, strlen(n), newSViv(i), 0);
}
RETVAL = sv_2mortal(newrv_noinc(val));
OUTPUT:
RETVAL
SV *
my_obj_b(o)
MyObject o
CODE:
SV *info = newHV();
hv_store(info, “b”, 1, newSVpvn(o->prop_b, strlen(o->prop_b)), 0);
int i;
for(i = 0; i < o->names.num; i++) {
const char *n = o->names.items[i];
hv_store(info, n, strlen(n), newSViv(i), 0);
}
RETVAL = sv_2mortal(newrv_noinc(val));
OUTPUT:
RETVAL
我想做的是分享像这样的实用函数中的一些功能
SV *create_obj_hash(MyObjectInfo *o, const char *k, const char *p) {
SV *val = newHV();
hv_store(val, k, strlen(k), newSVpvn(p, strlen(p)), 0);
int i;
for(i = 0; i < o->names.num; i++) {
const char *n = o->names.items[i];
hv_store(info, n, strlen(n), newSViv(i), 0);
}
return val;
}
MODULE = my_obj PACKAGE = MyObject PREFIX = my_obj_
SV *
my_obj_a(o)
MyObject o
CODE:
SV *info = create_obj_hash(o, “a”, o->prop_a);
RETVAL = sv_2mortal(newrv_noinc(val));
OUTPUT:
RETVAL
SV *
my_obj_b(o)
MyObject o
CODE:
SV *info = create_obj_hash(o, “b”, o->prop_b);;
RETVAL = sv_2mortal(newrv_noinc(val));
OUTPUT:
RETVAL
但是,当我在 create_obj_hash() 中进行宏扩展时失败,并显示以下消息。
myobj.xs: In function 'create_obj_hash':
/usr/lib/x86_64-linux-gnu/perl/5.28/CORE/perl.h:175:16: error: 'my_perl' undeclared (first use in this function); did you mean 'my_fork'?
# define aTHX my_perl
^~~~~~~
ppport.h:6145:41: note: in definition of macro 'MUTABLE_PTR'
# define MUTABLE_PTR(p) ({ void *_p = (p); _p; })
^
/usr/lib/x86_64-linux-gnu/perl/5.28/CORE/hv.h:651:17: note: in expansion of macro 'MUTABLE_HV'
#define newHV() MUTABLE_HV(newSV_type(SVt_PVHV))
^~~~~~~~~~
/usr/lib/x86_64-linux-gnu/perl/5.28/CORE/perl.h:188:18: note: in expansion of macro 'aTHX'
# define aTHX_ aTHX,
^~~~
/usr/lib/x86_64-linux-gnu/perl/5.28/CORE/embed.h:532:40: note: in expansion of macro 'aTHX_'
#define newSV_type(a) Perl_newSV_type(aTHX_ a)
^~~~~
/usr/lib/x86_64-linux-gnu/perl/5.28/CORE/hv.h:651:28: note: in expansion of macro 'newSV_type'
#define newHV() MUTABLE_HV(newSV_type(SVt_PVHV))
^~~~~~~~~~
myobj.xs:42:19: note: in expansion of macro 'newHV'
return (void*)newHV();
预先非常感谢您,
布莱恩