【问题标题】:Create SWIG C# wrapper for function that contains void* parameter为包含 void* 参数的函数创建 SWIG C# 包装器
【发布时间】:2014-08-14 14:24:43
【问题描述】:

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

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

默认情况下 SWIG 不处理 void 指针转换,您必须以某种方式使用类型映射。我找到了这个页面 -> 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'

据我所知,许多其他人也遇到了这个问题,关于如何解决这个问题的例子很少。有人可以帮我吗?

【问题讨论】:

    标签: c# c interface wrapper swig


    【解决方案1】:

    我试过了

    // 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 属性,它应该可以工作(因为我已经让它为我工作了)

    【讨论】:

      【解决方案2】:

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

      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 访问器似乎是关键。

      【讨论】:

        猜你喜欢
        • 2016-05-09
        • 1970-01-01
        • 2014-10-20
        • 1970-01-01
        • 2020-12-31
        • 2021-03-28
        • 2021-08-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多