问题
I'm trying to create a C# wrapper for a C .lib that contains functions take take a void pointer using SWIG.
int inputPointExample(void* input);
int outputPointerExample(void* output);
By default SWIG doesn't handle void pointer conversions, you have to use typemaps somehow. I found this page -> http://www.nickdarnell.com/2011/05/swig-and-a-miss/ Number 9 says to use the following typemaps to handle void pointers...
%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; }
When I try that I get a compile error in my exampleVectorType.cs in this function...
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
}
}
I got-
Cannot implicitly convert type 'SWIGTYPE_p_void' to 'System.IntPtr'
From what I was able to find, many others are having problems with this as well and there are only a few poor examples on how to fix this. Can someone help me out here?
回答1:
I've tried this with
// c++
void* GetRawPtr()
{
return (void*)_data;
}
which swigs to
// 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);
if the following line is removed, then i get the code you had:
%typemap(csout) void * { return $imcall; }
perhaps SWIG doesn't support typemapping well with properties? If you don't use get/set properties for your pData, it should work (as I've gotten it to work for me)
回答2:
I had a similar issue, but my case included struct fields:
struct foo {
void* bar;
};
I was able to get Swig to work by using this:
%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;
}
%}
I don't totally understand this stuff, but I believe the excode portion only matters if you're using exceptions. Overriding the property's get accessor via csvarout seems to be the key.
来源:https://stackoverflow.com/questions/25310530/create-swig-c-sharp-wrapper-for-function-that-contains-void-parameter