假设我理解正确你的问题,你有一些不透明的“处理”,在C是真的typedef
s到void*
,但在你生成的接口要强制执行强类型检查。 (请注意,默认行为在这里是正确的,因为它允许恰好镜像C的使用)。您希望防止意外地将一种类型的句柄提交给采用“不同”void*
的函数,即将typedef
作为strong typedef类型。
你可以用SWIG做到这一点,而不会有太多的麻烦。关键要记住的是,您给SWIG的接口文件并不总是必须与C类型完全匹配,只要最终生成的代码是正确的且合法的。
我举了一个例子来说明这一点。给定一个头文件,它在原理上与您ogr_api.h大概相似:
#include <stdio.h>
typedef void * HandleType1;
typedef void * HandleType2;
void foo(HandleType1) {printf("foo\n");}
void bar(HandleType2) {printf("bar\n");}
你只想能够调用foo
与HandleType1
和bar
有HandleType2
。
我用下面的接口来获得这样的行为:
%module test
%{
#include "test.h"
%}
%nodefaultctor HandleType1;
struct HandleType1 {};
%nodefaultctor HandleType2;
struct HandleType2 {};
void foo(HandleType1*);
void bar(HandleType2*);
%inline {
// just for testing - presumably you have a creator in your real API
HandleType1* geth1() { return NULL; }
HandleType2* geth2() { return NULL; }
}
是获取此生成的代码是完全正常的,虽然,因为它不尝试做任何事情不能用void*
完成和它们都被当作包装器中的指针来处理。
需要%nodefaultctor
来防止SWIG试图根据我们告诉它的谎言来构造一个新的句柄,否则会出现编译器错误。 (你可能想压制析构函数,或者自定义它,因为这将调用free
)。
它生成一个Java接口,只允许为每个函数使用正确的句柄。我测试了这一点:
public class run {
public static void main(String[] args) {
System.loadLibrary("test");
test.foo(test.geth1());
//test.bar(test.geth1());
//test.foo(test.geth2());
test.bar(test.geth2());
}
}
这有点一招,但它的作品,看看获取生成说服自己的包装。
编译并按预期运行。已注释的行会按照您的希望提供错误。
对于d具体的解决方案,在那里我明白typedef
给人以强烈的typedef(不像alias
这更像是用C typedef
)我认为你可以使用类似:
%module test
typedef void * HandleType1;
typedef void * HandleType2;
%pragma(d) proxydmodulecode = %{
typedef void * HandleType1;
typedef void * HandleType2;
%}
%typemap(dtype) HandleType1* "HandleType1";
%typemap(dtype) HandleType2* "HandleType2";
void foo(HandleType1* h1);
void bar(HandleType2* h2);
要生成你想要的接口。类型映射修改D接口中使用的类型,%pragma
将typedef
插入生成的接口的(代理)部分。
我认为你的目标语言是Java,尽管在这种情况下它应该没关系,但通常在SWIG问题中值得一提,因为某些功能/选项是语言特定的。 – Flexo 2012-07-22 17:14:46
为了以防万一 - 我的目标语言是D – Noname 2012-07-23 14:27:13
也许你应该尝试一下DStep - https://github.com/jacob-carlborg/dstep – DejanLekic 2012-07-23 22:30:28