在匿名类中使用方法参数会导致SIGSEGV(Using method parameters in anonymous class causes SIGSEGV)

编程入门 行业动态 更新时间:2024-10-27 12:32:46
在匿名类中使用方法参数会导致SIGSEGV(Using method parameters in anonymous class causes SIGSEGV)

我正在编写具有Java和本机部分的Android应用程序。 Java部分将消息发送到本机部分并接收回答。 本机部分完全在单独的线程上工作,当它返回答案时,我想在主线程上处理答案。 这是我扩展的Application类的一部分:

@Override public void OnMessage(final Message msg, final long answerTo) { Log.i(TAG, msg.ToStr()); // OK handler.post(new Runnable() { @Override public void run() { Log.i(TAG, msg.ToStr()); // Fatal signal 11 (SIGSEGV) // at 0x74616862 (code=1), thread 13255 } }); }

本机代码在其线程上调用OnMessage方法并尝试通过Handler将其传递给UI线程。 当我尝试在UI线程中使用任何msg方法时,我的程序会失败并使用SEGSEGV。

重要的事实是Message类是C ++ Message类的包装器。 包装由SWIG生成。

我尝试在GDB中调试它,GDB甚至向我展示了堆栈跟踪,它以本机Message.toStr方法结束。 但gdb拒绝打印变量,在当前上下文中说“无符号” * “。

请帮我解决这个问题。

I'm writing Android application that has Java and native part. Java part sends messages to native part and receives answers back. Native part does all work on separate thread and when it returns answer I want to handle answers on main thread. Here is part of my extended Application class:

@Override public void OnMessage(final Message msg, final long answerTo) { Log.i(TAG, msg.ToStr()); // OK handler.post(new Runnable() { @Override public void run() { Log.i(TAG, msg.ToStr()); // Fatal signal 11 (SIGSEGV) // at 0x74616862 (code=1), thread 13255 } }); }

Native code calls OnMessage method on it's thread and trying to pass it to UI thread through Handler. And when I try to use any method of msg inside UI thread my program fails with SEGSEGV.

Significant fact is that Message class is the wrapper for C++ Message class. Wrapper was generated by SWIG.

I tried to debug it in GDB, and GDB even shows me stack trace, which ends in native Message.toStr method. But gdb refuses to print variables, saying "No symbol "*" in current context".

Please, help me to resolve this issue.

最满意答案

我认为你没有正确使用Handler来做你想做的事情(跨线程复制对象)。 在这里查看博客文章:

http://techtej.blogspot.com/2011/02/android-passing-data-between-main.html

特别是向处理程序发送消息,如下所示:

Message msg = Message.obtain(); msg.obj = // Some Arbitrary object mHandler.sendMessage(msg);

我不认为你这样做的方式执行线程之间的数据复制的Handler魔术,因为它只是运行Runnable。

编辑:我很想知道这是不是问题所在,所以即使不是,你可以回复评论,让我知道结果吗?

编辑2:所以看起来你的对象可能被存储为JNI层中的本地引用。 不幸的是,这对您的目的来说还不够好,您可能需要将其作为全球参考。 请注意,如果您确实将其设为全局引用,则必须在完成本机代码后自行删除它。

http://developer.android.com/training/articles/perf-jni.html#local_and_global_references

Finally I solved problem by myself. The problem was, that when we make call from C++ to Java, SWIG proxy method passed pointer to it's argument to Java side. Something like:

void SwigDirector_NativeLayerDelegate::OnMessage(Message msg, Long answer_to) { ... *((Message **)&jmsg) = &msg; ... jenv->CallStaticVoidMethod(..., jmsg, ...); ... }

On Java side another proxy method recieved pointer, wrapped it with Java representation of Message class and passed it to Java method OnMessage:

public static void SwigDirector_NativeLayerDelegate_OnMessage( NativeLayerDelegate self, long msg, long answer_to) { self.OnMessage(new Message(msg, false), answer_to); // false parameter means that Message object isn't owner of 'msg' pointer, so it // shouldn't free it on finalize. }

After OnMessage finished, native Message object was destructed in SwigDirector_NativeLayerDelegate::OnMessage and Java Message object kept pointer to destructed native object.

Solution

I've wrote custom typemaps for my Message object:

%typemap(directorin,descriptor="L$packagepath/$javaclassname;") Message %{*((Message**)&$input) = new Message($1);%} %typemap(javadirectorin,descriptor="L$packagepath/$javaclassname;") Message %{new Message($1, true)%}

Now SwigDirector_NativeLayerDelegate::OnMessage creates copy of msg and Java object owns it:

// Native void SwigDirector_NativeLayerDelegate::OnMessage(Message msg, Long answer_to) { ... *((Message**)&jmsg) = new Message(msg); ... jenv->CallStaticVoidMethod(..., jmsg, ...); ... } // Java public static void SwigDirector_NativeLayerDelegate_OnMessage( NativeLayerDelegate self, long msg, long answer_to) { self.OnMessage(new Message(msg, true), answer_to); }

更多推荐

本文发布于:2023-08-05 19:25:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1437744.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:使用方法   类中   参数   SIGSEGV   class

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!