关于C库中回调C++函数的库依赖的一些问题(题目比较特殊回答前能先耐心看完题目)

bandaoyu 2018-01-20 07:12:39

这是我的程序文件b.cpp中函数



#ifdef __cplusplus
extern "C" {
#endif
int32 callback_for_c(int32 lIdentifyCode,int16 nMsgType,void *pstMsg,int32 lMsgLen)
{

Php::Value relt;
printf("callback c function sucess!\n");

// call a function from user space 调用用户的函数
Php::Value data = Php::call("some_function", "some_parameter");

printf("%s\n", "i arrival here!");

return int32_t(relt);
}

#ifdef __cplusplus
}
#endif



Php::Value phpHwntp_InitComm(Php::Parameters ¶meters)
{

ST_HW_SERVERINFO_PARAM stHwServerInfoParam[1]=
{
{0,"192.168.4.251",60507,callback_for_c}
};


int32 relt;

//first parameter
Php::Value phpServerID = parameters[0];
//second parameter
Php::Value phpServerPort = parameters[1];

Php::Value phpServerIpAddr = parameters[2];

Php::Value phpFnServerInfoTableLen = parameters[3];

relt = Hwntp_InitComm(stHwServerInfoParam,TABLESIZE(stHwServerInfoParam));

printf("Hwntp_InitComm relt = %d\n", relt);

return relt;

}




Hwntp_InitComm()是comm.a中的函数,stHwServerInfoParam是它的参数,定义是:

typedef ubool (*FN_HW_MSG_HANDLER) (int32 lIdentifyCode,int16 nMsgType,void *pstMsg,int32 lMsgLen);

typedef struct tagST_HW_SERVERINFO_PARAM
{
int32 lServerID;
int8 pcServerIpAddr[64];
int32 lServerPort;
FN_HW_MSG_HANDLER fnMsgHandler;
}ST_HW_SERVERINFO_PARAM;




所以callback_for_c 函数其实就是通过指针fnMsgHandler带回给Hwntp_InitComm的回调函数。

callback_for_c中的 Php::call()函数中的 function 是C++11的特性:


template <typename ...Params>
Value call(const char *name, Params&&... params)
{
// the name can be turned into a Php::Value object, which implements
// the operator () method to call it
Value function(name);

// invoke the operator ()
return function(std::forward<Params>(params)...);
}





我的问题来了:



comm.a 是在机器A上编译的,机器A上的gcc是4.4版本的,也就是不支持C++11,应该就没有function特性。

而comm.a中的函数Hwntp_InitComm 回调了callback_for_c,callback_for_c中有 Php::call(), Php::call()依赖function。

这样,Hwntp_InitComm是不是就无法正常执行Php::call()?实际上也确实出现了段错误。

#0 0x006c19f0 in _emalloc ()
#1 0xb6f57374 in zend_string_alloc (persistent=0, len=13) at /usr/include/php-zts/php/Zend/zend_string.h:122
#2 zend_string_init (persistent=0, len=13, str=0xb6ff0181 "some_function") at /usr/include/php-zts/php/Zend/zend_string.h:158
更多相关内容可看:http://bbs.csdn.net/topics/392309417


是不是comm.a也要在支持C++11的编译器件上编译并且将-std=c++11库链进去才可以?

我们编译b.cpp的时候(b.cpp在机器B上编译,机器B上的gcc是4.8,支持C++11,编译出来的程序也是在机器B上执行),Php::Value data = Php::call("some_function", "some_parameter"); 这一句所有相关的代码(function……等)和依赖(c++11等)没有编到函数callback_for_c里面吗?callback_for_c最终不就是一个二进制的代码块吗? 对执行它的库/环境还有要求?






...全文
562 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2018-01-22
  • 打赏
  • 举报
回复
Saleayas 2018-01-21
  • 打赏
  • 举报
回复
如果你使用静态库来编译,那么需要注意这些库的版本的一致性。 因为他们是静态链接的。不同库的在内存布局上可能有所不同。 你可以看看 VS 在静态库上有很多的版本,同一个版本的静态库也有编译模式的不同。 在看看 Boost 都是这样的。 但是在很多编译器链接不同的版本会提示错误的。不知道你的为什么。 你的问题的表现是我感觉是内存错误,你不要尝试调用函数,直接创建一个 Value 试试,是否之内存错误。 可以把不同版本的静态库编译为共享库,然后链接到一起。
bandaoyu 2018-01-21
  • 打赏
  • 举报
回复
引用 9楼paschen 的回复:
引用 8 楼 bandaoyu 的回复:
引用 7楼paschen 的回复:
[quote=引用 6 楼 bandaoyu的回复:][quote=引用 3 楼 paschen 的回复:]是否支持C++11是编译层面上的,生成的机器码是没有这些区分的,再次建议你注意调用约定等问题,如果代码量很大,建议先写一个简单的程序来研究,再放到你项目中去
问题在于看上去在调用约定上是没有问题呀,callback_for_c 是调用正常的,而Php::call()的调用,也进到了#0   in _emalloc ()#1   in zend_string_alloc (persistent=0, len=13) #2  zend_string_init (persistent=0, len=13, str=0xb6ff0181 "some_function") 是在_emalloc ()的地方死掉的其实我将Php::Value data = Php::call("some_function", "some_parameter");  这一句话放在b.cpp的其他位置是可以正常执行的,而且我打断点看到到zend_string_alloc (persistent=0, len=13) 这个位置的参数值persistent=0, len=13 和放在callback_for_c里面的时候到这个位置也是一样的,然而前者在_emalloc ()没崩溃,后者在_emalloc ()崩了,所以我就想是只能是猜想 执行这一句的环境不一样
检查是否是其他问题导致,你先看下函数中没有任何内容是否会崩,检查是否是使用堆内存越界导致堆破坏
你也看到了,我标注的在哪里崩溃的了在这里崩溃的#0   in _emalloc ()
#1   in zend_string_alloc (persistent=0, len=13) 
#2  zend_string_init (persistent=0, len=13, str=0xb6ff0181 "some_function") 

是在_emalloc ()的地方死掉的

其实我将Php::Value data = Php::call("some_function", "some_parameter");  这一句话放在b.cpp的其他位置是可以正常执行的,而且我打断点看到到zend_string_alloc (persistent=0, len=13) 这个位置的参数值persistent=0, len=13 和放在callback_for_c里面的时候到这个位置也是一样的,然而前者在_emalloc ()没崩溃,后者在_emalloc ()
崩了,一样的函数,一样的参数,一个挂了一个没挂,所以我就想是只能是猜想 执行这一句的环境不一样[/quote]检查是否是使用堆内存越界导致堆破坏,必要时可注释所有使用堆内存的语句,看是否能正常申请内存[/quote]一样的函数,一样的参数,一个挂了一个没挂。所以应该不是函数的问题。 没挂的是在b.cpp中执行,挂的是回调到comm.a中执行,是在里面创建了一个新线程,执行callback_for_c。
paschen 版主 2018-01-21
  • 打赏
  • 举报
回复
引用 8 楼 bandaoyu 的回复:
引用 7楼paschen 的回复:
引用 6 楼 bandaoyu的回复:
[quote=引用 3 楼 paschen 的回复:]是否支持C++11是编译层面上的,生成的机器码是没有这些区分的,再次建议你注意调用约定等问题,如果代码量很大,建议先写一个简单的程序来研究,再放到你项目中去
问题在于看上去在调用约定上是没有问题呀,callback_for_c 是调用正常的,而Php::call()的调用,也进到了#0   in _emalloc ()#1   in zend_string_alloc (persistent=0, len=13) #2  zend_string_init (persistent=0, len=13, str=0xb6ff0181 "some_function") 是在_emalloc ()的地方死掉的其实我将Php::Value data = Php::call("some_function", "some_parameter");  这一句话放在b.cpp的其他位置是可以正常执行的,而且我打断点看到到zend_string_alloc (persistent=0, len=13) 这个位置的参数值persistent=0, len=13 和放在callback_for_c里面的时候到这个位置也是一样的,然而前者在_emalloc ()没崩溃,后者在_emalloc ()崩了,所以我就想是只能是猜想 执行这一句的环境不一样
检查是否是其他问题导致,你先看下函数中没有任何内容是否会崩,检查是否是使用堆内存越界导致堆破坏
你也看到了,我标注的在哪里崩溃的了在这里崩溃的#0   in _emalloc ()
#1   in zend_string_alloc (persistent=0, len=13) 
#2  zend_string_init (persistent=0, len=13, str=0xb6ff0181 "some_function") 

是在_emalloc ()的地方死掉的

其实我将Php::Value data = Php::call("some_function", "some_parameter");  这一句话放在b.cpp的其他位置是可以正常执行的,而且我打断点看到到zend_string_alloc (persistent=0, len=13) 这个位置的参数值persistent=0, len=13 和放在callback_for_c里面的时候到这个位置也是一样的,然而前者在_emalloc ()没崩溃,后者在_emalloc ()
崩了,一样的函数,一样的参数,一个挂了一个没挂,所以我就想是只能是猜想 执行这一句的环境不一样[/quote]检查是否是使用堆内存越界导致堆破坏,必要时可注释所有使用堆内存的语句,看是否能正常申请内存
bandaoyu 2018-01-21
  • 打赏
  • 举报
回复
引用 7楼paschen 的回复:
[quote=引用 6 楼 bandaoyu的回复:] [quote=引用 3 楼 paschen 的回复:] 是否支持C++11是编译层面上的,生成的机器码是没有这些区分的,再次建议你注意调用约定等问题,如果代码量很大,建议先写一个简单的程序来研究,再放到你项目中去
问题在于看上去在调用约定上是没有问题呀,callback_for_c 是调用正常的,而Php::call()的调用,也进到了 #0   in _emalloc () #1   in zend_string_alloc (persistent=0, len=13)  #2  zend_string_init (persistent=0, len=13, str=0xb6ff0181 "some_function")  是在_emalloc ()的地方死掉的 其实我将Php::Value data = Php::call("some_function", "some_parameter");  这一句话放在b.cpp的其他位置是可以正常执行的,而且我打断点看到到zend_string_alloc (persistent=0, len=13) 这个位置的参数值persistent=0, len=13 和放在callback_for_c里面的时候到这个位置也是一样的,然而前者在_emalloc ()没崩溃,后者在_emalloc () 崩了,所以我就想是只能是猜想 执行这一句的环境不一样[/quote] 检查是否是其他问题导致,你先看下函数中没有任何内容是否会崩,检查是否是使用堆内存越界导致堆破坏[/quote]你也看到了,我标注的在哪里崩溃的了 在这里崩溃的 #0   in _emalloc ()
#1   in zend_string_alloc (persistent=0, len=13) 
#2  zend_string_init (persistent=0, len=13, str=0xb6ff0181 "some_function") 

是在_emalloc ()的地方死掉的

其实我将Php::Value data = Php::call("some_function", "some_parameter");  这一句话放在b.cpp的其他位置是可以正常执行的,而且我打断点看到到zend_string_alloc (persistent=0, len=13) 这个位置的参数值persistent=0, len=13 和放在callback_for_c里面的时候到这个位置也是一样的,然而前者在_emalloc ()没崩溃,后者在_emalloc ()
崩了,一样的函数,一样的参数,一个挂了一个没挂,所以我就想是只能是猜想 执行这一句的环境不一样
paschen 版主 2018-01-21
  • 打赏
  • 举报
回复
引用 6 楼 bandaoyu的回复:
[quote=引用 3 楼 paschen 的回复:] 是否支持C++11是编译层面上的,生成的机器码是没有这些区分的,再次建议你注意调用约定等问题,如果代码量很大,建议先写一个简单的程序来研究,再放到你项目中去
问题在于看上去在调用约定上是没有问题呀,callback_for_c 是调用正常的,而Php::call()的调用,也进到了 #0   in _emalloc () #1   in zend_string_alloc (persistent=0, len=13)  #2  zend_string_init (persistent=0, len=13, str=0xb6ff0181 "some_function")  是在_emalloc ()的地方死掉的 其实我将Php::Value data = Php::call("some_function", "some_parameter");  这一句话放在b.cpp的其他位置是可以正常执行的,而且我打断点看到到zend_string_alloc (persistent=0, len=13) 这个位置的参数值persistent=0, len=13 和放在callback_for_c里面的时候到这个位置也是一样的,然而前者在_emalloc ()没崩溃,后者在_emalloc () 崩了,所以我就想是只能是猜想 执行这一句的环境不一样[/quote] 检查是否是其他问题导致,你先看下函数中没有任何内容是否会崩,检查是否是使用堆内存越界导致堆破坏
bandaoyu 2018-01-21
  • 打赏
  • 举报
回复
引用 3 楼 paschen 的回复:
是否支持C++11是编译层面上的,生成的机器码是没有这些区分的,再次建议你注意调用约定等问题,如果代码量很大,建议先写一个简单的程序来研究,再放到你项目中去
问题在于看上去在调用约定上是没有问题呀,callback_for_c 是调用正常的,而Php::call()的调用,也进到了 #0   in _emalloc () #1   in zend_string_alloc (persistent=0, len=13)  #2  zend_string_init (persistent=0, len=13, str=0xb6ff0181 "some_function")  是在_emalloc ()的地方死掉的 其实我将Php::Value data = Php::call("some_function", "some_parameter");  这一句话放在b.cpp的其他位置是可以正常执行的,而且我打断点看到到zend_string_alloc (persistent=0, len=13) 这个位置的参数值persistent=0, len=13 和放在callback_for_c里面的时候到这个位置也是一样的,然而前者在_emalloc ()没崩溃,后者在_emalloc () 崩了,所以我就想是只能是猜想 执行这一句的环境不一样
super_admi 2018-01-21
  • 打赏
  • 举报
回复
#ifdef __cplusplus
 extern "C" {
 #endif
 int32 callback_for_c(int32 lIdentifyCode,int16 nMsgType,void *pstMsg,int32 lMsgLen)
 {

  Php::Value relt;
  printf("callback  c function sucess!\n");

   // call a function from user space  调用用户的函数 
   Php::Value data = Php::call("some_function", "some_parameter");

   printf("%s\n", "i arrival here!");

  return int32_t(relt);
 }

 #ifdef __cplusplus
 }
 #endif
改成:
#ifdef __cplusplus
 extern "C" 
 #endif
 int32 callback_for_c(int32 lIdentifyCode,int16 nMsgType,void *pstMsg,int32 lMsgLen)
 {

  Php::Value relt;
  printf("callback  c function sucess!\n");

   // call a function from user space  调用用户的函数 
   Php::Value data = Php::call("some_function", "some_parameter");

   printf("%s\n", "i arrival here!");

  return int32_t(relt);
 }
super_admi 2018-01-21
  • 打赏
  • 举报
回复
你那个extern "C"不要把整个函数都括起来,只定义在函数名前面试试。
引用 2 楼 bandaoyu 的回复:
[quote=引用 1楼super_admi 的回复:]我去,这么久了,你这个问题还没法解决?我认为你的判断是错误的。另外找一个路,或者换一个思路解决问题吧。
不管换不换思路,我还是希望能把原因搞清楚。 为什么php::call 放在回调函数callback_for_c里面就不行,在b.cpp的其他地方就可以。我想应该是一个很简单的错误造成的,只是我们没有找出来[/quote]
paschen 版主 2018-01-21
  • 打赏
  • 举报
回复
是否支持C++11是编译层面上的,生成的机器码是没有这些区分的,再次建议你注意调用约定等问题,如果代码量很大,建议先写一个简单的程序来研究,再放到你项目中去
bandaoyu 2018-01-21
  • 打赏
  • 举报
回复
引用 1楼super_admi 的回复:
我去,这么久了,你这个问题还没法解决?我认为你的判断是错误的。另外找一个路,或者换一个思路解决问题吧。
不管换不换思路,我还是希望能把原因搞清楚。 为什么php::call 放在回调函数callback_for_c里面就不行,在b.cpp的其他地方就可以。我想应该是一个很简单的错误造成的,只是我们没有找出来
super_admi 2018-01-20
  • 打赏
  • 举报
回复
我去,这么久了,你这个问题还没法解决?我认为你的判断是错误的。另外找一个路,或者换一个思路解决问题吧。

64,690

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧