Boost.Interprocess v1.66 - 带有C#

时间:2018-03-20 11:28:29

标签: c# c++ boost boost-interprocess

我在Boost.Interprocess(v1.66)库中遇到问题,我在C / C ++库中使用它,我在C#中通过编组使用(从C#调用C本机代码)。

如果我使用Boost.Interprocess named_semaphore进行进程间的同步,我发现了问题。 (在open_or_create模式下)

如果我将C / C ++ lib与其他本机C / C ++代码一起使用,一切正常(在最新的Windows 10,Linux(4+内核)甚至Mac OS X(> = 10.11)下)。 问题发生在Windows下 - 使用C#我有C ++代码的C包装器。如果我使用简单的自己构建EXE的编组 - >一切正常!但是如果我在第三方应用程序中使用相同的C#代码(使用相同的C lib)作为DLL插件,我在named_semaphore中从get_bootstamp获得了segfault。

所以我有第三方C#SW为其创建插件(C#DLL)。在该插件中,我通过编组使用我的C库。编组工作在测试C#项目中工作正常(它只从C lib调用C函数)但在第三方软件中使用相同的代码段错误。

C图书馆工作流程:

  • 初始化所有必要的C结构
  • 使用Boost.Process
  • 启动所需的TCP服务器(本机C / C ++应用程序)
  • 等待服务器(通过named_semaphore)< - segfault
  • 连接服务器......

C#代码具有相同的工作流程。

发现问题

问题发生在boost::interprocess::ipcdetail::get_booststamp(在named_semaphore中调用)。这里:

  struct windows_bootstamp
  {
     windows_bootstamp()
     {
        //Throw if bootstamp not available
        if(!winapi::get_last_bootup_time(stamp)){
           error_info err = system_error_code();
           throw interprocess_exception(err);
        }
     }
     //Use std::string. Even if this will be constructed in shared memory, all
     //modules/dlls are from this process so internal raw pointers to heap are always valid
     std::string stamp;
  };

  inline void get_bootstamp(std::string &s, bool add = false)
  {
     const windows_bootstamp &bootstamp = windows_intermodule_singleton<windows_bootstamp>::get();
     if(add){
        s += bootstamp.stamp;
     }
     else{
        s = bootstamp.stamp;
     }
  }

如果我调试到行

const windows_bootstamp &bootstamp = windows_intermodule_singleton<windows_bootstamp>::get()

booststamp.stamp不可读。大小设置为31,容量设置为一些奇怪的值(如19452345),数据不可读。如果我走到

s += bootstamp.stamp; 

发生了段错误!

找到原因

我再次调试并将调试点设置为windows_bootstamp构造函数条目,但没有命中,因此标记未初始化(我猜)。

确认

如果我将get_bootstamp更改为

  inline void get_bootstamp(std::string &s, bool add = false)
  {
     const windows_bootstamp &bootstamp = windows_intermodule_singleton<windows_bootstamp>::get();
     std::string stamp;
     winapi::get_last_bootup_time(stamp);
     if(add){
        s += stamp;
     }
     else{
        s = stamp;
     }
  }

重新编译我的lib和exe - 一切正常(没有任何问题)。

我的问题是 - 我做错了什么?我非常彻底地阅读了Boost.Interprocess文档但是没有关于我的问题的建议/警告(是的,在Interprocess doc中有&#34; COM Initialization&#34;但它似乎没有帮助。)

或者它只是Boost.interprocess中的一个错误,我可能会将它报告给Boost bug跟踪器?

注意 - 如果我手动启动服务器(在运行C#代码之前)它没有segfaults

0 个答案:

没有答案