- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在 Ubuntu 中使用 SWIG 2.0.10 来调用 Java 中的 C++ 代码。
我的 C++ 代码是:
//ImgPro.h:
#include <vector>
typedef struct _bin
{
char* name;
float value;
} Bin;
typedef struct imgprops
{
std::vector<Bin> color;
int width;
int height;
char *print;
} ImageProperties;
class ImgPro
{
public:
ImgPro();
ImageProperties *processImage(char* imagePath);
};
processImage函数定义为:
ImageProperties* ImgPro::processImage(char *imagePath)
{
ImageProperties* imgProp = new ImageProperties();
imgProp->width = 200;
imgProp->height = 200;
char* fp = new char(5);
strcpy(fp, "abc!");
imgProp->print = fp;
Bin outputBin1;
char *name1 = new char(strlen("red")+1);
strcpy(name1, "red");
outputBin1.name = name1;
outputBin1.value = 0.125;
Bin outputBin2;
char *name2 = new char(strlen("blue")+1);
strcpy(name2, "blue");
outputBin2.name = name1;
outputBin2.value = 0.27;
vector<Bin> tempVec;
tempVec.push_back(outputBin1);
tempVec.push_back(outputBin2);
imgProp->color = tempVec;
return imgProp;
因此,为了使用 swig 生成 jni 代码,我使用了以下 swig 文件(注意:vector.i 文件是使用此 example 创建的):
%module CBIR
// to handle char** has String_Array in Java
%include <various.i>
%include "vector.i"
%{
#include "ImgPro.h"
%}
// to handle char** has String_Array in Java
%apply char **STRING_ARRAY { char ** };
// memory release
%extend imgprops {
~imgprops(){
if($self != NULL)
{
// releasing print element
if($self->print != NULL)
delete[] $self->print;
// releasing vector elements
for(uint x = 0; x < $self->color.size(); x++)
{
Bin currentBin = $self->color[x];
if(currentBin.name != NULL)
delete[] currentBin.name;
}
// releasing stuct Pointer
delete $self;
}
}
}
%include "ImgPro.h"
%template(BinVec) std::vector<Bin>;
这会在 swig_wrap 文件中生成下一个函数:
SWIGINTERN void delete_imgprops(imgprops *self){
if(self != NULL)
{
// releasing print element
if(self->print != NULL)
delete[] self->print;
// releasing vector elements
for(uint x = 0; x < self->color.size(); x++)
{
Bin currentBin = self->color[x];
if(currentBin.name != NULL)
delete[] currentBin.name;
}
// releasing stuct Pointer
delete self;
}
}
在 delete ImageProperties c++ 函数中调用。
但是,在 Java 中运行以下代码永远不会释放在 C++ 中分配的内存(调用函数 delete_imgprops):
ImgPro imgObject = new ImgPro();
ImageProperties propObject = imgObject.processImage("imagem123-jpg");
int width = propObject.getWidth();
int height = propObject.getHeight();
String fingerPrint = propObject.getPrint();
propObject.delete();
imgObject.delete();
于是,通过分析代码流程,找到了内存没有释放的原因。 SWIG 生成的 ImageProperties.Java 文件包含删除功能等:
public synchronized void delete() {
if (swigCPtr != 0) {
if (swigCMemOwn) {
swigCMemOwn = false;
CBIRJNI.delete_ImageProperties(swigCPtr);
}
swigCPtr = 0;
}
}
行“CBIRJNI.delete_ImageProperties(swigCPtr);”永远不会被调用,因为 var swigCMemOwn 始终为假。
我了解到,因为 Java 端不分配内存,所以它也不释放它,那么我该怎么做才能确保 java 释放内存而不对 swig 生成的 java 文件进行任何修改?
我发现释放内存的解决方案是在 delete() 函数上注释 if(swigCMemOwn) 测试,但我认为这不是最好的方法!
谢谢,塞尔吉奥
最佳答案
你可以看看
%newobject
带有工厂方法的指令(在 swig 2.0 中)。它告诉 swig,一个特定的函数将返回一个新对象,并且 java 代理类也应该负责清理 c++ 内存。生成的代码会将 swigCMemOwn 设置为 true,从而导致调用 c++ 析构函数。
如果您确实自己调用了 delete 方法,那很好 - 您只需改变您的编程风格,将 swig'ed 对象视为类似于文件句柄或数据库连接的东西。完成后,您会在这些对象上调用 close(),因为您不想等待 Java 的 GC 在以后某个未知的时间点启动并收集这种昂贵的资源 - 您希望手动管理它。
但是您显然还必须记住遵守良好的代码纪律,以确保在调用 delete() 后不会在任何地方使用 java 对象
关于java - SWIG java : releasing memory allocated in c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21068884/
我认为我的问题与“https://serverfault.com/q/299179”和“https://serverfault.com/q/283330/71790”有些相关,但其中任何一个都没有令我
我生成了 APK 对于我的 flutter 项目和 F:\build\app\outputs\apk\release 我有 3 种类型的 apk 文件,包括 output.json 文件。他们是: *
我们最近决定更新 Beta release 的新应用程序在 Google Play 上, 现在读完指南后,我心里有一些问题,想了解更多,我用谷歌搜索进一步了解找到了一些答案,但还有一些我不确定的东西,
我正在尝试使用发布管理作为构建版本的工具,但我很难理解码件、工具和操作之间的真正区别。有人可以分解这三个概念之间的差异以及它们如何相互配合吗? 最佳答案 由于它适用于基于代理的版本: 工具旨在提供自定
我最近完成了使用 jgitflow:release-finish 合并一个发布分支来掌握和开发。 .构建成功。 但是现在我正在尝试使用 jgitflow:releast-start 创建一个新分支.但
我一直在读到,如果一个集合“被释放”,它也会释放它的所有对象。另一方面,我还读到,一旦集合被释放,集合就会释放它的对象。 但最后一件事可能并不总是发生,正如苹果所说。系统决定是否取消分配。在大多数情况
我在具有以下布局的多模块项目上使用 maven-release-plugin: ROOT/ + parent + module1 + module2 在parent的pom中,使用modu
我正在使用 ionic 构建移动应用。 我面临一个严重的问题。 我必须使用 on-touch 和 on-release 事件,但问题是每当我触摸时,on-release 甚至也会立即触发而没有实际释放
谁能解释清楚两者之间的区别是什么.Release()和->Release() 在 CComPtr 上? 确切地说,两种情况下内存管理是如何发生的? 最佳答案 CComPtr 的operator-> 函
两个片段有什么区别? [myObj release]; 和 [myObj release]; myObj = nil; 最佳答案 如果你只是释放一个对象,那么它就会变成释放对象。 如果您尝试对已释放的
我正在运行 maven 发布插件 (org.apache.maven.plugins:maven-release-plugin:2.3.2) 并注意到当通过命令行。我想知道是否有办法关闭它。 我使用
我正在尝试通过运行nuget pack -properties Configuration=Release命令来更新我的nuget软件包,但这会给我以下错误: Unable to find 'bin/
我们正在使用 Microsoft 的发布管理将我们的 Web 应用程序部署到我们的测试环境 (QA)。它是一个直接的 MVC.Net Web 应用程序。我们的构建生成一个 web 部署包,我们有一个命
我有一个在 X 环境中发布的版本 A。另一方面,我有一个在环境 Y 中发布的版本 B。 问题是我想知道我是否可以在版本 B 中检查版本 A 的状态,这样我就可以抛出错误而不发布版本 B。 我不知道是否
我正在开发一个使用大量图像的应用程序,我正在使用 UIWebView 使用 JavaScript 代码(我正在使用 UIZE 库)来表示大约 200 张图像,问题当我完成 UIWebView 时,我在
我已阅读 Marshal.GetIUnknownForObject 的文档它说: Always use Marshal.Release to decrement the reference count
为了成为 iPhone SDK 上的好内存公民,我一直在玩内存。 然而,我仍然很难理解"self.something" 和只是"something" 之间的区别。 据我了解,"self.somethi
我需要使用 bash 找出我正在运行的 Linux 发行版。找到this page ,这非常有帮助。 但是我的系统有两个/etc/*-release 文件 /etc/lsb-release /etc/
我想使用 Maven Release Plugin 将 Release Candidates 发布到我的 Nexus Snapshot 存储库。 将 RC 部署到 Nexus 不是问题,但我想利用 m
在什么情况下我们应该使用“Latch until release”而不是“Switch until release”? 根据 LabVIEW 2011 Help : Latch until relea
我是一名优秀的程序员,十分优秀!