代码之家  ›  专栏  ›  技术社区  ›  MartyIX

在C中创建管道和必要的权限#

  •  1
  • MartyIX  · 技术社区  · 14 年前

    我尝试在C语言中添加一个SokBooBover(C++编写)到我的程序中(我在我的程序中有一个类,用来处理C++接口的编组)。我的程序加载solver.dll库,该库加载solver.exe。solver.dll和solver.exe通过管道进行通信。

    问题是,当我在Visual Studio(调试)中运行我的程序时,DLL加载正常,插件的功能也很好。但是,当我在Visual Studio之外打开程序(简单双击my program.exe)时,当我尝试运行求解函数时,会出现错误消息:“got invalid pipe”和“failed to create pipe.”。

    我很迷茫可能是什么问题,但我猜有些权限有问题。

    以下是插件作者的两部分代码:

    在solver.dll文件中:

     //create pipes
     SECURITY_ATTRIBUTES attr;
     attr.nLength=sizeof(attr);
     attr.lpSecurityDescriptor=NULL;
     attr.bInheritHandle=TRUE;
     if(!CreatePipe(&hPipeOutRead,&hPipeOutWrite,&attr,0)
             ||!CreatePipe(&hPipeInRead,&hPipeInWrite,&attr,0) )
     {
             ReportError("Failed to create pipe.");
             return SOKOBAN_PLUGIN_RESULT_FAILURE;
     }
    
     //set std handle for deliver pipe
     HANDLE hStdInSave, hStdOutSave;
     hStdInSave=GetStdHandle(STD_INPUT_HANDLE);
     hStdOutSave=GetStdHandle(STD_OUTPUT_HANDLE);
     if(hStdInSave==INVALID_HANDLE_VALUE || hStdOutSave==INVALID_HANDLE_VALUE)
     {
             ReportError("Failed to get std handles.");
             return SOKOBAN_PLUGIN_RESULT_FAILURE;
     }
     if(!SetStdHandle(STD_INPUT_HANDLE,hPipeOutRead)
             ||!SetStdHandle(STD_OUTPUT_HANDLE,hPipeInWrite) )
     {
             ReportError("Failed to redirect std handles.");
             return SOKOBAN_PLUGIN_RESULT_FAILURE;
     }
    
     //create BoxSearch Process
     STARTUPINFO startInfo;
     ZeroMemory(&startInfo,sizeof(startInfo));
     startInfo.cb=sizeof(startInfo);
    
     PROCESS_INFORMATION processInfo;
     ZeroMemory(&processInfo,sizeof(processInfo));
    
     char dllDir[MAX_PATH];
     char exeName[MAX_PATH+100];
     GetModuleFileName(ghinstDLL,dllDir,MAX_PATH);
     *(strrchr(dllDir,'\\')+1)=0;
     strcpy(exeName,dllDir);
     strcat(exeName,"Solver.exe");
    
     char cmdLine[MAX_PATH+100];
     strcpy(cmdLine,"\"");
     strcat(cmdLine,exeName);
     strcat(cmdLine,"\"");
     strcat(cmdLine," ");
     strcat(cmdLine,API_DLLCommandLine);
    
     BOOL launchSuccess=CreateProcess(exeName,cmdLine,NULL,NULL,TRUE,0,NULL,dllDir,&startInfo,&processInfo);
    

    solver.exe一侧:

    //get pipes
     hPipeRead=GetStdHandle(STD_INPUT_HANDLE),
     hPipeWrite=GetStdHandle(STD_OUTPUT_HANDLE);
     if(0==hPipeRead || INVALID_HANDLE_VALUE==hPipeRead
             ||0==hPipeWrite|| INVALID_HANDLE_VALUE==hPipeWrite)
     {
             FormattedMessageBox("Got invalid pipe.");
             return;
     }
    

    可能有什么问题?是否有与加载的dll(用于管道)相关的权限?

    谢谢!

    1 回复  |  直到 14 年前
        1
  •  2
  •   Hans Passant    14 年前

    哎呀,那很容易。只有当myprogram.exe是控制台模式应用程序时,这才能很好地工作。需要才能使输入/输出重定向工作。由于Visual Studio宿主进程,它可能在调试器中工作。

    在程序中调用alloconsole可以解决这个问题。我猜你不会特别在意控制台窗口,你必须重写这个接口。使用命名管道可以解决这个问题。实际上,将解算器作为单独的进程运行没有任何意义。看看C++/CLI以取得领先。