C++调用go函数出错,哪位大师给查查?

m
minquan
楼主 (未名空间)


go:

-----------------------------
//export OnLogin_1
func OnLogin_1(status C.int) {
fmt.Println("target1 ok:", status)
}
=============================

h:
-----------------------------
typedef void (*nfun)(int LoginStatus);
extern nfun OnLogin_1;
=============================

cpp:
-----------------------------
std::cout << "=====Login Succeeded @" << this->target << std::endl;
if(this->target==1) OnLogin_1(1);
=============================

运行时候最后两行为:
=====Login Succeeded @1
段错误,已经保存

这个段错误是咋出来的呢?是不是哪里语法不对?
m
mitbbs2715

不是大师, 也不需要大师

你编译通过了, 多数不是c call go的问题, 问题多数出在c++. 你问的问题其实会非常让人恼火, 因为你代码没有贴全, 也没有stack trace. 有诚意的话, 你用lldb导出
stack trace贴出来.

注意你用了 `extern nfun OnLogin_1;` 但你却没有贴你如何dlopen 动态获得
OnLogin_1. 这谁知道你哪儿出问题了. 你应该用ASAN检查你的代码, 至少应该先初始化为nullptr, 然后在使用OnLogin_1之前总是assert(OnLogin_1). 如果你总是这样写
代码, 你的code reviewer估计会被气疯. 尽量不要用extern, 在这里显然非常容易导
致错误. 你应该包装一个golib object, 在 golib constructor 里面dlopen, 如果无
法dlopen应该throw, golib object应该own一个uniqe ptr来存lib handle, 并且在
constructor里面assert你是否能得到有效的func
pointer, 其他地方通过 golib.OnLogin_1(xx) 来调用. RAII, 基本中的基本

你的cpp里面用了好多this, 感觉不是很好, 除非你是用的lambda, 但同样没有相应代码支持, 如果是我学生这么问c++问题, 我肯定给不及格.

m
minquan

额,是这样,我是在人家开发好的代码上二次开发。
我不知道lldb或stack trace,问题就在于它不是纯c++程序,也不是纯go的程序,所以就两不管。

这个主程序是go调用c++的lib去连接一个金融行情接口
然后每一个接口会起用单独一个交易所给定的class,这就是this的来源。

target可以有若干个,这里只举例第1个,即第一个行情地址。

因为交易所定义的交互是先去连接它,然后连上了就请求登录,如果登录成功了它就会调用一个函数。

然后我在这个函数里面写了调用go的OnLogin_1
实际上就把1这个整数传回go
然后让go据此下一步行动。这里要做的只是把它打印出来。

当然,我打算在连接断开是也调用这个函数,只是会传0.
在go里面定义了该函数,是export出去,即放在C里面。

而C++里面用的extern,意思是这个函数不是C,而是C++的
所以我从go里面定义,到C去得知并调用都写了,应该算是很全了。

【 在 mitbbs2715 (好吃不懒做) 的大作中提到: 】
: 不是大师, 也不需要大师
: 你编译通过了, 多数不是c call go的问题, 问题多数出在c++. 你问的问题其实会非常
: 让人恼火, 因为你代码没有贴全, 也没有stack trace. 有诚意的话, 你用lldb导出
: stack trace贴出来.
: 注意你用了 `extern nfun OnLogin_1;` 但你却没有贴你如何dlopen 动态获得
: OnLogin_1. 这谁知道你哪儿出问题了. 你应该用ASAN检查你的代码, 至少应该先初始
: 化为nullptr, 然后在使用OnLogin_1之前总是assert(OnLogin_1). 如果你总是这样写
: 代码, 你的code reviewer估计会被气疯. 尽量不要用extern, 在这里显然非常容易导
: 致错误. 你应该包装一个golib object, 在 golib constructor 里面dlopen, 如果无
: 法dlopen应该throw, golib object应该own一个uniqe ptr来存lib handle, 并且在
: ...................

m
mitbbs2715

1. 你对extern理解有误, 请去看看C++的基本教程

2. 而且你如果用func pointer你必须动态dlopen, 是不能通过linker来连接, 可以去
看看基本的 c教程

3. 如果你不知道怎么动态加载库, 你就完全没必要这么用. 直接 `extern void
OnLogin_1(int);` 即可通过linker连接. 你可以自己随便写个go文件编译成库, 就有
自动生成的header, 你可以看看里面是怎么写的.

我的建议, 鉴于你缺乏基本的C/C++ 常识, 与其自己乱试浪费时间, 不如花上3天好好
找本C++的书看看, 看完以后你几个小时就能搞定一切.

初学者就不要随便用指针了, 指针都需要封装到很底部, 最烦看到满篇指针的程序.

【 在 minquan (三民主义) 的大作中提到: 】
: 额,是这样,我是在人家开发好的代码上二次开发。
: 我不知道lldb或stack trace,问题就在于它不是纯c++程序,也不是纯go的程序,所以
: 就两不管。
: 这个主程序是go调用c++的lib去连接一个金融行情接口
: 然后每一个接口会起用单独一个交易所给定的class,这就是this的来源。
: target可以有若干个,这里只举例第1个,即第一个行情地址。
: 因为交易所定义的交互是先去连接它,然后连上了就请求登录,如果登录成功了它就会
: 调用一个函数。
: 然后我在这个函数里面写了调用go的OnLogin_1
: 实际上就把1这个整数传回go
: ...................

m
minquan

你对this这么大气干嘛?
人家交易所给的接口就是要这样写
一个连接是一个class,也是一个thread

【 在 mitbbs2715 (好吃不懒做) 的大作中提到: 】
: 1. 你对extern理解有误, 请去看看C++的基本教程
: 2. 而且你如果用func pointer你必须动态dlopen, 是不能通过linker来连接, 可以去
: 看看基本的 c教程
: 3. 如果你不知道怎么动态加载库, 你就完全没必要这么用. 直接 `extern void
: OnLogin_1(int);` 即可通过linker连接. 你可以自己随便写个go文件编译成库, 就有
: 自动生成的header, 你可以看看里面是怎么写的.
: 我的建议, 鉴于你缺乏基本的C/C++ 常识, 与其自己乱试浪费时间, 不如花上3天好好
: 找本C++的书看看, 看完以后你几个小时就能搞定一切.
: 初学者就不要随便用指针了, 指针都需要封装到很底部, 最烦看到满篇指针的程序.

b
bravesalmon

能给推荐一本三五天能看完的c++书吗?不要那种六百页加的。我就是业余c++,经常出一些诡异的错误。

【 在 mitbbs2715 (好吃不懒做) 的大作中提到: 】
: 1. 你对extern理解有误, 请去看看C++的基本教程
: 2. 而且你如果用func pointer你必须动态dlopen, 是不能通过linker来连接, 可以去
: 看看基本的 c教程
: 3. 如果你不知道怎么动态加载库, 你就完全没必要这么用. 直接 `extern void
: OnLogin_1(int);` 即可通过linker连接. 你可以自己随便写个go文件编译成库, 就有
: 自动生成的header, 你可以看看里面是怎么写的.
: 我的建议, 鉴于你缺乏基本的C/C++ 常识, 与其自己乱试浪费时间, 不如花上3天好好
: 找本C++的书看看, 看完以后你几个小时就能搞定一切.
: 初学者就不要随便用指针了, 指针都需要封装到很底部, 最烦看到满篇指针的程序.