为包含void *参数的函数创建SWIG C#包装器

时间:2014-08-14 14:24:44

标签: c# c interface wrapper swig

我试图为包含函数的C .lib创建一个C#包装器,使用SWIG获取一个void指针。

int inputPointExample(void* input);
int outputPointerExample(void* output);

默认情况下,SWIG不处理无效指针转换,您必须以某种方式使用类型映射。我找到了这个页面 - > http://www.nickdarnell.com/2011/05/swig-and-a-miss/ 数字9表示使用以下类型映射来处理void指针...

%typemap(ctype)  void * "void *"
%typemap(imtype) void * "IntPtr"
%typemap(cstype) void * "IntPtr"
%typemap(csin)   void * "$csinput"
%typemap(in)     void * %{ $1 = $input; %}
%typemap(out)    void * %{ $result = $1; %}
%typemap(csout)  void * { return $imcall; }

当我尝试在此函数中的exampleVectorType.cs中出现编译错误时...

public IntPtr pData {
set {
  examplePINVOKE.ExampleVectorType_pData_set(swigCPtr, value);
} 
get {
  global::System.IntPtr cPtr = examplePINVOKE.ExampleVectorType_pData_get(swigCPtr);
  SWIGTYPE_p_void ret = (cPtr == global::System.IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false);
  return ret; //Compile error occurs here
    } 
}

我得到了 -

Cannot implicitly convert type 'SWIGTYPE_p_void' to 'System.IntPtr'

从我能够找到的,许多其他人也遇到了这方面的问题,并且只有一些关于如何解决这个问题的不好的例子。有人可以帮助我吗?

2 个答案:

答案 0 :(得分:3)

我用

试过了
// c++
void* GetRawPtr()
{
    return (void*)_data;
}

向哪个人打招呼

// swig generated c#
// Example.cs
IntPtr GetRawPtr()
{
    return examplePINVOKE.Example_GetRawPtr(swigCPtr);
} 

// examplePINVOKE.cs
[global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_Example_GetRawPtr")]
public static extern IntPtr Example_GetRawPtr(global::System.Runtime.InteropServices.HandleRef jarg1);

如果删除了以下行,那么我将获得您拥有的代码:

%typemap(csout)  void * { return $imcall; }

或许SWIG不支持使用属性进行打字?如果你没有为你的pData使用get / set属性,它应该工作(因为我已经让它为我工作)

答案 1 :(得分:1)

我有类似的问题,但我的案例包括结构字段:

struct foo {
   void* bar;
};

我能够通过使用这个来使Swig工作:

%typemap(ctype)  void* "void *"
%typemap(imtype) void* "System.IntPtr"
%typemap(cstype) void* "System.IntPtr"
%typemap(csin)   void* "$csinput"
%typemap(in)     void* %{ $1 = $input; %}
%typemap(out)    void* %{ $result = $1; %}
%typemap(csout, excode=SWIGEXCODE)  void* { 
    System.IntPtr cPtr = $imcall;$excode
    return cPtr;
    }
%typemap(csvarout, excode=SWIGEXCODE2) void* %{ 
    get {
        System.IntPtr cPtr = $imcall;$excode 
        return cPtr; 
   } 
%} 

我并不完全理解这些内容,但我相信,如果您使用异常,则excode部分才有意义。通过csvarout覆盖属性的get访问器似乎是关键。