Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SWIG_csharp_string_回调在从C+;传递字符串(const char*)时导致内存泄漏+;到C# 我在使用Sigg导演从C++到C.*传递字符串(const char *)参数时,面临内存泄漏。我在swig论坛中发现了类似的问题,并提出了一些有价值的建议,但是,缺少一套正确的类型图(即使在当前的swig版本2.0.11中,这个问题也没有得到解决)_C#_C++_Memory Leaks_Swig - Fatal编程技术网

SWIG_csharp_string_回调在从C+;传递字符串(const char*)时导致内存泄漏+;到C# 我在使用Sigg导演从C++到C.*传递字符串(const char *)参数时,面临内存泄漏。我在swig论坛中发现了类似的问题,并提出了一些有价值的建议,但是,缺少一套正确的类型图(即使在当前的swig版本2.0.11中,这个问题也没有得到解决)

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操作系

在花了几天的时间在谷歌上搜索和研究swig代码后,我终于写了一套打字图,为我解决了这个问题


我希望这个问题和贴出的答案能对我有所帮助。

这是一套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);
  }
}