使用Swig Director将字符串(const char *)参数从C++传递到C#时,我面临内存泄漏。我在swig论坛中发现了类似的question,并提供了一些有值(value)的建议,但是,缺少正确的类型映射集(即使在当前的swig版本2.0.11中也未解决该问题)。
花了几天的时间进行谷歌搜索并研究了Swig代码之后,我终于写了一组类型图,为我解决了这个问题。
我希望这个问题和发布的答案会有所帮助。
最佳答案
这是为我完成工作的char *的类型映射集。
想法是将char *作为IntPtr传递给C#,然后使用InteropServices.Marshal.StringToHGlobalAnsi()
将其转换为C#字符串(C#字符串将被GC销毁)。同样,将字符串从C#传递到C++时,我们使用InteropServices.Marshal.StringToHGlobalAnsi()
方法将其转换为IntPtr(并确保一旦调用返回,该对象将最终被销毁)。
// Alternative char * typemaps.
%pragma(csharp) imclasscode=%{
public class SWIGStringMarshal : IDisposable {
public readonly HandleRef swigCPtr;
public SWIGStringMarshal(string str) {
swigCPtr = new HandleRef(this, System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(str));
}
public virtual void Dispose() {
System.Runtime.InteropServices.Marshal.FreeHGlobal(swigCPtr.Handle);
GC.SuppressFinalize(this);
}
~SWIGStringMarshal()
{
Dispose();
}
}
%}
%typemap(ctype) char* "char *"
%typemap(cstype) char* "string"
// Passing char* as an IntPtr to C# and then convert it to a C# string.
%typemap(imtype, out="IntPtr") char * "HandleRef"
%typemap(in) char* %{$1 = ($1_ltype)$input; %}
%typemap(out) char* %{$result = $1; %}
%typemap(csin) char* "new $imclassname.SWIGStringMarshal($csinput).swigCPtr"
%typemap(csout, excode=SWIGEXCODE) char *{
string ret = System.Runtime.InteropServices.Marshal.PtrToStringAnsi($imcall);$excode
return ret;
}
%typemap(csvarin, excode=SWIGEXCODE2) char * %{
set {
$imcall;$excode
} %}
%typemap(csvarout, excode=SWIGEXCODE2) char * %{
get {
string ret = System.Runtime.InteropServices.Marshal.PtrToStringAnsi($imcall);$excode
return ret;
} %}
%typemap(directorout) char* %{$result = ($1_ltype)$input; %}
%typemap(csdirectorout) char * "$cscall"
%typemap(directorin) char *
%{
$input = (char*)$1;
%}
%typemap(csdirectorin) char* "System.Runtime.InteropServices.Marshal.PtrToStringAnsi($iminput)";
ps。我在Windows 32/64和Linux 64操作系统上测试了类型映射。
关于c# - 从C++向C#传递字符串(const char *)时,SWIG_csharp_string_callback导致内存泄漏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20994262/