- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试调用 C++ 函数:
void TestFunc(void(*f)(void)) { f(); }
来自 Go 代码。
我真的希望我只是将一个 Go 函数传递给该函数。我知道我可以将它包装到一个类中,并使用 %feature("director") 解决它,但这不是我的最佳解决方案。
根据我在 this page 中看到的内容,Go 中指向函数的指针,应该与 C++ 中的相同,所以我尝试了以下 .swig 文件:
%{
#include "test.h"
%}
%typemap(gotype) FUNC* "func()"
%typemap(in) FUNC* {
$1 = (void(*)(void))$input;
}
%apply FUNC* { void(*)(void) };
%include "test.h"
一开始我很惊讶它能奏效,但后来发现它并不总是奏效:(。
例如,在这段 Go 代码中,它按预期工作:
import "fmt"
import "test_wrap"
func main() {
b := false
test_wrap.TestFunc(func() { b = true })
fmt.Println(b) // This actually DOES print "true"!
}
但在其他情况下,它不起作用。例如,这里:
import "fmt"
import "test_wrap"
func main() {
test_wrap.TestFunc(func() { fmt.Println("SUCCESS") })
fmt.Println("Done")
}
我实际上得到:
SUCCESS
SIGILL: illegal instruction
PC=0x4c20005d000
goroutine 1 [syscall]:
test_wrap._swig_wrap_TestFunc(0x400cb0, 0x400c2a)
base_go_test__wrap_gc.c:33 +0x32
test_wrap.TestFunc(0x400cb0, 0x2)
base_go_test__wrap.go:37 +0x25
main.main()
test.go:8 +0x2a
goroutine 2 [syscall]:
created by runtime.main
go/gc/src/pkg/runtime/proc.c:225
rax 0x0
rbx 0x0
rcx 0x0
rdx 0x8
rdi 0x4c200073050
rsi 0x4c20004c0f0
rbp 0x0
rsp 0x4c20004c100
r8 0x2
r9 0x4b0ae0
r10 0x4f5620
r11 0x4dbb88
r12 0x4f5530
r13 0x7fad5977f9c0
r14 0x0
r15 0x3
rip 0x4c20005d000
rflags 0x10202
cs 0x33
fs 0x0
gs 0x0
请注意它确实打印了“SUCCESS”,这意味着该函数 DID 运行了,即使我将更复杂(和更长)的代码放入该函数中,它也能完美执行,但它没有返回: (.
请告诉我您的想法,以及我如何解决这个问题。我不介意在 C++ 部分添加一些代码,但我真的希望 Go 部分看起来“干净”。
谢谢。
最佳答案
成功了!我有一个有效的解决方案:
我所做的想法是用“directors”包装回调,并将 Go 函数指针“返回”回 Go,因此它可以在该上下文中运行。
下面的解决方案并不完美,但已足够满足我的需求,从这里开始完善它也很容易。
C++ 文件:
class Callback {
public:
virtual void Run(void(*f)(void)) = 0;
virtual ~Callback() {}
};
Callback* GlobalCallback;
void TestFunc(void(*f)(void)) {
GlobalCallback->Run(f);
}
我添加了一个 Callback 类,它将在 Go 中“扩展”(使用 Swig Controller ),并且我将拥有这个扩展类的全局实例。因此,调用该实例的 Run() 将调用一个 Go 函数,该函数将接收一个函数指针。
请注意我的 TestFunc 现在不只是运行 f(),而是通过 GlobalCallback 运行它。通过添加另一个返回指向运行 GlobalCallback->Run(f) 的函数的指针的函数,并将该指针而不是 *f 传递给该函数,可以很容易地解决这个问题。
我的 Swig 文件:
%{
#include "test.h"
%}
%module(directors="1") Callback
%feature("director");
%typemap(gotype) FUNC* "func()"
%typemap(in) FUNC* {
$1 = (void(*)(void))$input;
}
%apply FUNC* { void(*)(void) };
%include "test.h"
%insert(go_wrapper) %{
type go_callback struct { }
func (c* go_callback) Run(f func()) {
f()
}
func init() {
SetGlobalCallback(NewDirectorCallback(&go_callback{}))
}
%}
请注意,我添加了一个 init() 函数,它使用运行指针的 Go 函数设置 GlobalCallback。
就是这样,Go 代码就这样了,它可以工作:)
关于c++ - 通过 SWIG 从 C++ 调用 Go 回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14003078/
我正在制作一个 C++ 库的包装器,以便它可以从 Java 中使用,我正在用 Swig 做这个。 我面临的是我有一个类(class) SomeClass ,它有一些重载的方法( someMethod
我有许多要在 SWIG 中重命名的类。我的大部分类(class)看起来像这样some_class ,我想将其重命名为 SomeClass .这很简单: %replace("%(camelcase)s"
PyPy 有一些 compatibility limitations ,尤其是关于 CPython C API。 我用 QuickFix预编译的 SWIG 绑定(bind)附带的包,我正在考虑将它与
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 9年前关闭。 Improve this q
使用 SWIG 生成接口(interface)模块时,生成的 C/C++ 文件包含大量静态样板函数。因此,如果想通过在同一个应用程序中使用许多单独编译的小接口(interface)来模块化 SWIG
我正在应用 SWIG 手册中有关嵌套类的解决方法,该部分使用全局内部类。在这里,我将向您展示一个类似于手册中的版本,但为您尽可能地简化了。我还必须将内联定义 {} 添加到 method(),因为没有它
我有一个现有的库 (JPhysX),它是原生 C++ 库 (PhysX) 的 Java 包装器。 Java 库使用 SWIG 生成的类型,例如 com.jphysx.SWIGTYPE_p_NxStre
有没有办法动态向下转换 swig 对象的 swig 代理? 这样做的原因是为了模拟 C++ 向下转换,但纯粹来自 python。例如,典型的 C++ 用法是 MyBase* obj = new MyB
我在远程服务器上工作,所以我在本地安装了 swig,使用 -prefix=/home/user/directory。 我有一个来自同事的 makefile,其中包含以下命令: swig $(SWIG_
据我所知,在用于将 c++ 文件编译为 python 扩展模块的 .i 文件中,我们可以添加一些 python 代码,如下所示(来自 example for adding additional pyt
我的 Swig 文件 (.i) 中有以下代码: %extend vgSofa::handler::VertexShape { vgd::Shp createVSWithNode( so
我有一个用 swig 包装的类的 C++ 代码。我无法修改代码或包装。在 python 中,我使用 ctypes 拥有一个指向所述 C++ 类的实例的指针。如何围绕该指针创建一个 swig 包装器?
我开始掌握 SWIG 的窍门,SWIG 的最新版本 (v3.0) 似乎可以处理我开箱即用所需的一切,包括 C++11 功能,但我遇到了麻烦开始在我的导演类(class)中使用 shared_ptr。
我正在使用 javacode 类型映射来添加一些附加函数来代替 SWIG 生成的函数。我想删除 SWIG 为 unsigned char mac[6]; 生成的默认 getter 和 setter(p
我正在使用 SWIG 为我的 C 库生成 Python 语言绑定(bind)。我已经设法构建了绑定(bind)和导出的数据结构,但在使用该库时我不得不跳过一些障碍。 例如,C 头文件的数据类型和函数原
我最近在node-js应用程序中从jade模板引擎切换到了swig。在使用jade时我使用了命令 jade.render('/sample.jade',{obj:object});渲染模板并传递对象。
我在我的 python 代码中发现了瓶颈,尝试了 Psycho 等。然后决定编写一个 c/c++ 扩展来提高性能。 在 swig 的帮助下,您几乎不需要关心参数等。一切正常。 现在我的问题是:swig
由于 SWIG 无法解析 __attribute__((packed))在我想包装的一些 C 结构上,我通过放置一个 #define __attribute__(x) 在我的.i文件。 这什么时候会来
我有一个包含 C++ header 的 SWIG 文件。 痛饮文件: %module my_module %{ #include "my_c_file.h" %} %include "my_c_fil
我正在尝试学习如何使用 SWIG,并且想知道我是否正在执行一些不需要执行的额外步骤。我目前有文件 Dog.cpp、Dog.h 和 Dog.i。我正在尝试使用 SWIG 包装 Dog.cpp 以便在 P
我是一名优秀的程序员,十分优秀!