d - 与 SWIG 绑定 - 类型定义类型绑定不正确



我有类似的swig.I文件:

%module ogr_api
%{
#include "ogr_api.h"
%}
%inline %{
typedef void *OGRSFDriverH;
%}
/* OGRSFDriverRegistrar */
OGRDataSourceH OGROpen( const char *, int, OGRSFDriverH * )`

我得到以下.c包装:

...
SWIGEXPORT void * D_OGROpen(char * jarg1, int jarg2, void * jarg3) {
...

这就是SWIG将OGRSFDriverH翻译为void。我需要保存类型名称。我该怎么做?

我在第一个论点中也失去了const,但这是下一个问题。

假设我正确理解了你的问题,你有很多不透明的"句柄",在C中它们实际上是typedefvoid*,但在你生成的接口中,你希望强制执行更强的类型检查。(请注意,这里的默认行为是正确的,因为它允许使用完全镜像C的方法)。您希望防止一种类型的句柄意外地被赋予采用"不同"void*的函数,即将typedef公开为某种强typedef。

使用SWIG可以做到这一点,而不会遇到太多麻烦。需要记住的关键是,您给SWIG的接口文件并不总是必须与真正的C类型完全匹配,只要最后生成的代码是正确合法的。

我举了一个例子来说明这一点。给定一个头文件,其原理可能与您的ogr_api.h类似:

#include <stdio.h>
typedef void * HandleType1;
typedef void * HandleType2;
void foo(HandleType1) {printf("foon");}
void bar(HandleType2) {printf("barn");}

您希望只能用HandleType1调用foo,用HandleType2调用bar

我使用以下界面来获得这样的行为:

%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接口中使用的类型,%pragmatypedef插入生成接口的(代理)部分。

最新更新