SWIG_csharp_string_回调在从C+;传递字符串(const char*)时导致内存泄漏+;到C# 我在使用Sigg导演从C++到C.*传递字符串(const char *)参数时,面临内存泄漏。我在swig论坛中发现了类似的问题,并提出了一些有价值的建议,但是,缺少一套正确的类型图(即使在当前的swig版本2.0.11中,这个问题也没有得到解决)
在花了几天的时间在谷歌上搜索和研究swig代码后,我终于写了一套打字图,为我解决了这个问题SWIG_csharp_string_回调在从C+;传递字符串(const char*)时导致内存泄漏+;到C# 我在使用Sigg导演从C++到C.*传递字符串(const char *)参数时,面临内存泄漏。我在swig论坛中发现了类似的问题,并提出了一些有价值的建议,但是,缺少一套正确的类型图(即使在当前的swig版本2.0.11中,这个问题也没有得到解决),c#,c++,memory-leaks,swig,C#,C++,Memory Leaks,Swig,在花了几天的时间在谷歌上搜索和研究swig代码后,我终于写了一套打字图,为我解决了这个问题 我希望这个问题和贴出的答案能对我有所帮助。这是一套char*的打字图,它帮了我的忙 其思想是将char*作为IntPtr传递给C#,然后使用InteropServices.Marshal.StringToHGlobalAnsi()(C#字符串将被GC销毁)。类似地,当从C到C++传递字符串时,我们将其转换成一个带有“代码>互操作”的IMPTR。 另外,我在Windows 32/64和Linux 64操作系
我希望这个问题和贴出的答案能对我有所帮助。这是一套char*的打字图,它帮了我的忙 其思想是将char*作为IntPtr传递给C#,然后使用
InteropServices.Marshal.StringToHGlobalAnsi()
(C#字符串将被GC销毁)。类似地,当从C到C++传递字符串时,我们将其转换成一个带有“代码>互操作”的IMPTR。
另外,我在Windows 32/64和Linux 64操作系统上测试了这些类型映射。这是一个已知的错误,多年前在SWIG org上就有报道,请参阅 和 此错误在最新版本中尚未修复(到目前为止是版本4.0.2) 代码的错误在swig\Lib\csharp\std\u string.i中。使用bug,当有字符串回调时,它在我的应用程序中生成C++中的函数:
void SwigDirector_MyCode::LogDebug(std::string const &message) {
char * jmessage = 0 ;
if (!swig_callbackLogDebug) {
throw Swig::DirectorPureVirtualException("SDS::ISDSLogger::LogDebug");
} else {
jmessage = SWIG_csharp_string_callback((&message)->c_str());
swig_callbackLogDebug(jmessage);
}
}
LogDebug应该从C++代码调用。 在代码中,jmessage是新分配的内存。您可以在调用后更改jmessage中的第一个字符来验证它,并且可以看到(&message)->c_str()没有更改
有观点认为应该调用free()或delete来释放从SWIG_csharp_string_callback()创建的内存 但这对我不起作用。我用SWIG从C++生成C ^包装器。 我的解决方案是为project.i文件中的std::string const&类型定义新的类型映射%typemap(directorin) const std::string & %{ $input = const_cast<char *>($1.c_str()); %}
%typemap(directorin)const std::string&%%{$input=const_cast($1.c_str());%}
因此,我生成的代码变成:
void SwigDirector_MyCode::LogDebug(std::string const &message) {
char * jmessage = 0 ;
if (!swig_callbackLogDebug) {
throw Swig::DirectorPureVirtualException("MyCode::LogDebug");
} else {
jmessage = const_cast<char *>((&message)->c_str());
swig_callbackLogDebug(jmessage);
}
}
void SwigDirector\u MyCode::LogDebug(std::string const&message){
char*jmessage=0;
如果(!swig_callbackLogDebug){
抛出Swig::DirectorPureVirtualException(“MyCode::LogDebug”);
}否则{
jmessage=const_cast((&message)->c_str());
swig_callbackLogDebug(jmessage);
}
}
在这段代码中,不再分配jmessage
它已经通过VS2017在Debian 9 mono和Windows 7上进行了测试 >我很困惑为什么会发生这种情况,我在一个大的应用程序中使用SWIG在C和C++之间传递了字符串,并且从来没有观察到内存泄漏(在某个点上有一些漏洞,但不是由于这个原因)。听起来你找到了一个很好的解决方案。引用自:如果C回调将托管字符串返回给C(在SWIG#csharp#u string#回调方法中发生),似乎是因为.Net或Mono会分配一个非托管字符串并将其返回给本机代码,因为否则,返回的值(如果它实际指向托管对象)将需要固定,但这不会发生。因此,新分配的内存没有被清理,这可能导致内存泄漏。
void SwigDirector_MyCode::LogDebug(std::string const &message) {
char * jmessage = 0 ;
if (!swig_callbackLogDebug) {
throw Swig::DirectorPureVirtualException("MyCode::LogDebug");
} else {
jmessage = const_cast<char *>((&message)->c_str());
swig_callbackLogDebug(jmessage);
}
}