| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2537 人关注过本帖
标题:在 VS 下调用 MinGW 做个自己的编译器 IDE,该方案是否可行?
只看楼主 加入收藏
天使梦魔
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:37
帖 子:564
专家分:2754
注 册:2007-8-29
收藏
得分:6 
我去。。。。挂参数啊。那几个编译是接受参数的。
无式和函数启动exe,在xxx.exe后面空格然后加参数。用管道传回所得信息。

16位main有2个,32位winmain有4个。你可以自己写程序测试下,你下载的那几个文件都接受传参的,用这个方法最简单,在核心调用什么命令就用参数调用,写到程序的时候用字符串自己组合。

管道通讯的话参考下
http://bbs.



不过我建议你用第个方法测试
2014-08-25 23:28
cr945211
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2014-7-31
收藏
得分:0 
回复 11 楼 天使梦魔
不好意思,这两句话我不是太懂 “无式和函数启动exe,在xxx.exe后面空格然后加参数”
                               “16位main有2个,32位winmain有4个。你可以自己写程序测试下”
   可以解释下吗?
2014-08-26 22:02
天使梦魔
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:37
帖 子:564
专家分:2754
注 册:2007-8-29
收藏
得分:6 
打错了而已,我意思你测试的时候不要用管道去发送,而是使用参数形式
2014-08-27 08:31
cr945211
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2014-7-31
收藏
得分:0 
回复 13 楼 天使梦魔
对,我测试过,输入命令的时候没有用管道,只是输出的时候用管道重定向到VS界面中。但出现的问题是,给它一个命令后,CMD运行一下就关闭了,然后得到了执行结果。但是,我不可能只给它一个命令,需要好多命令(比如调试的时候),而这些命令也是上下关联的,比如输入gdb命令,则进入调试环境,然后才能设断点、调试等等。
    我用CreateProcess()做的,没有用输入管道,只能完成gcc -o helloworld.exe helloworld.c这种一个命令就能完成的操作。

[ 本帖最后由 cr945211 于 2014-8-27 10:06 编辑 ]
2014-08-27 09:30
天使梦魔
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:37
帖 子:564
专家分:2754
注 册:2007-8-29
收藏
得分:0 
可以不使用输入管道,但一定要用管道去得到执行结果,这个执行结果不是最后的exe,而是gcc.exe从cmd里返回出的信息.输入管道只是可以用在编译时隐藏过程的.
如果你不去返回信息很难做.意思是"用管道得到cmd执行信息",而不是编译后的结果.
比如你有个程序是
main()
{
  int a=9,b=1;
  cout<<a+b;
}

这个时候通过管道得到cout的部分,也就是显示在cmd上的东西,你不能在程序内部申请一个变量去用=号进行操作.
就好比假设上面是我写的一个程序,输出a+b结果,你再做一个程序在内部申请字符串变量然后启动我的程序,得到我程序的输出信息,这就是管道作用.

gcc/g++ 这种编译核如果你无法用管道去获得回馈信息,而是看编译成功没那也太那个什么了.(当然你可以使用cmd输出成txt保存信息)
我以前下过gcc手册,里面的命令将近100左右,全是各种参数以及说明,不过我删掉了,你在mingw官网也能下载到英文版的手册.(可以百度下gcc手册,有中文版的)
我不太了解你到底哪里不熟悉或者有问题,看法是如何的.
但...做一个编译器真不是轻松的活,这仅仅是开始而已,不然编译器早烂大街了.
2014-08-27 15:56
cr945211
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2014-7-31
收藏
得分:0 
回复 15 楼 天使梦魔
你好,谢谢你的耐心回答,发过好多帖子,水平有限,只能这样一步步来啊
比如我这里有个加法程序 add.cpp
程序代码:
using namespace std;
int main()
{
    int a,b,c;
    cout<<"加法计算器:\n"<<endl;
    cout<<"a= "<<endl;
      cin>>a;
    cout<<"b= "<<endl;
       cin>>b;    
    cout<<"结果为:";
        c=a+b;
    cout<<c<<endl;   
    return 0;
}

   我明白你说的问题,这也是我之前想过的。如果将g++ -o add.exe add.cpp发给CMD后,只是在同目录下生成了add.exe文件,只是返回到CMD窗口中的结果,如果现在我再将add.exe命令发给CMD,也只是显示**a= b=,不能像CMD一样可以输入值再执行。。所以,单看这个加法程序的问题,我是不是要再定义一个线程,CreateProcess(),参数写成add.exe,然后输入两个值给该程序,这样可以得到结果吗?还是说要输入gdb add.exe,然后run,然后给a和b的值?
   如果是第二个方法,就会遇到我一直在问的问题,像你所说的,输入管道只是隐藏了过程,但是我现在没有办法做到让所有的命令都是在同一个CMD下进行(在系统CMD下,肯定是先gdb然后才能在<gdb>下run的,也就是说这些命令上下有关联),而是执行完gdb后,如果再给run他肯定就不认得该命令(CMD下没有run这个命令),那如果想进一步调试,也是不可能的。。这个问题困扰我太久了,真的不知道涉及的什么知识。
2014-08-27 17:44
天使梦魔
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:37
帖 子:564
专家分:2754
注 册:2007-8-29
收藏
得分:0 
线程和这个没联系啊,如果新线程能做那主线程为什么不能做?
线程只是让一个程序占用cpu两个时间而已,一个线程不影响另一个消息泵堵塞。但并不代表用线程去执行本体外程序就可以共享内存和接口。
第二个方法,为什么要同时运行?如果使用cmd就不停的挂上exe,每条命令都有一个前端运行程序,gui保存设置好路径,每条参数前都带运行程序exe
你说的必须进入gdb然后运行某命令我暂时理解为不支持参数调用。这时候你找管道输入资料,管道输入就是直接以某exe已经打开然后进行操作,如果使用输入就不要用挂参形式了而是程序内可执行的所有命令。格式也以直接打开exe后怎么输入为准
2014-08-27 19:01
cr945211
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2014-7-31
收藏
得分:0 
回复 17 楼 天使梦魔
第一个方法我的意思是,之前不是用CreateProess启动的cmd.exe嘛,那现在生成了add.exe,是不是再定义一个CreateProcess启动add.exe,然后传a,b的值。。。。。
  后面你解释的我有点听不懂(我水平有限啊)。“如果使用cmd就不停的挂上exe,每条命令都有一个前端运行程序,gui保存设置好路径,每条参数前都带运行程序exe”这句话的意思,联系我用的MinGW命令,我理解的是:比方说我编译、链接一个C程序,参数为-o,那用到的是gcc.exe,那我给的命令就是“gcc -o ………”,如果编译、链接一个C++程序,参数也是-o,用到的是g++.exe,那我给的命令就是“g++ -o ………”。应该是这样吧。。gui保存设置好路径指的什么啊?
  后面这句话“你说的必须进入gdb然后运行某命令我暂时理解为不支持参数调用。”我给你发了一个在CMD中运行的图片,当输入gdb add.exe 命令后会进入<gdb>下,也就是调试环境中(因为我后期的重点、难点肯定在调试这一块,设置断点、单步什么的,都要在<gdb>下进行),然后我可以输入run等其他调试时用到的命令。。
图片附件: 游客没有浏览图片的权限,请 登录注册

   
  “这时候你找管道输入资料,管道输入就是直接以某exe已经打开然后进行操作,如果使用输入就不要用挂参形式了而是程序内可执行的所有命令。格式也以直接打开exe后怎么输入为准”这句话真的说到我心坎儿上了,我感觉问题就是在这里,比方说我现在给gdb命令,打开了调试环境,那我以后都要在这个环境下执行命令,是不是说这个时候用管道输入就可以了。比如说以下语句
        si.hStdInput = hStdinRd;//数据输入用的文件句柄
    si.hStdError = hStdoutWr;//数据输出用的文件句柄
    si.hStdOutput = hStdoutWr;//数据输出用的文件句柄

程序代码:
  void COutputWnd::WriteToPipe(LPCTSTR line)
{
   DWORD dwWritten;
   WriteFile( hStdinWr, line, _tcslen(line)*sizeof(TCHAR), 
            &dwWritten, NULL );
}

是这个思考方向吗?

[ 本帖最后由 cr945211 于 2014-8-28 22:33 编辑 ]
2014-08-28 22:32
天使梦魔
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:37
帖 子:564
专家分:2754
注 册:2007-8-29
收藏
得分:0 
gui是图形用户界面,百度一下就知道了啊,我说的gui指的是你的编译器ui,总的有配置程序吧...

不过你自己做匿名管道,居然连它的概念也不明白?
我没做过,网上抄的:
程序代码:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <stdio.h>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{ 
    HANDLE hpiperead = NULL , hpipewrite = NULL; 
    SECURITY_ATTRIBUTES ai;     //安全属性  
    ai.nLength = sizeof(SECURITY_ATTRIBUTES); 
    ai.bInheritHandle = true ; 
    ai.lpSecurityDescriptor = NULL ; 

 
    if (!CreatePipe(&hpiperead , &hpipewrite , &ai ,0 ))  //创建管道  
    { 
        printf("创建匿名管道失败\n"); 
        return 0; 
    } 
     
    char com[1024]; //控制命令  
    char buff[255]; 
    cin>>buff; 

 
    strcpy( com , "cmd.exe /c" );
    strcat( com , buff); 

 

 
    STARTUPINFO si; 
    PROCESS_INFORMATION pi;      
    GetStartupInfo(&si);    //获取当前进程的STARTUPINFO  
    si.cb = sizeof(STARTUPINFO); 
    si.hStdError = hpipewrite ; 
    si.hStdOutput = hpipewrite ; 
    si.wShowWindow = SW_SHOW ; 
    si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES; 

 
    if (!CreateProcess(NULL , com , NULL , NULL , true , NULL,NULL , NULL , &si , &pi)  )      //创建隐藏的CMD进程  
    { 
        CloseHandle(hpipewrite); 
        CloseHandle(hpiperead) ; 
        cout<<"1"<<endl; 
        return 0; 
    } 
    char outbuff[4096]; 
     
    DWORD byteread; 
    while (1) 
    { 
        memset( outbuff ,'\0' ,4096 ); 
        if (ReadFile(hpiperead , outbuff , 4095 , &byteread , NULL) == NULL) 
        { 
            break; 
        } 
        printf("%s",outbuff); 
        memset( outbuff ,'\0' ,4096 ); 
    } 

 
    cout<<endl; 

 
    //创建内核对象使用完之后一定记得关闭,有可能会产生内存泄露  
 
    CloseHandle(hpipewrite); 
    CloseHandle(hpiperead) ; 
    CloseHandle(pi.hProcess); 
    CloseHandle(pi.hThread) ; 

 
    return 0; 
}
我的是vs2008, strcpy函数不支持utf8的字符集,如果你也是,自己配置下工程属性,设置里面,把字符集改成未设置就变车管acii码了.
运行之后它就挂接cmd程序了,你可以输入一个cmd命令比如help,然后得到所有帮助列表回馈.
你也可以自己写个程序.比如
int main()
{
  cout<<"test";
}
编译后把这个程序的exe复制到上面一个exe目录下,然后把strcpy指向你这个的exe,编译运行后,随便输入什么然后回车就可以得到回馈了.(网上抄的代码很烂,有bug,不过我没做过匿名管道,所以我就不去深入了)

通过以上,你可以看到,匿名管道链接后可以发送命令和得到回馈,也就是你想要的结果(模拟直接打开exe然后输入).另外奉劝你一句,做线程的时候不要用CreateProess,我从没用过,我只用安全线程beginthreadex,这个函数没有统一的标准,每个编译器对这个函数的用法都不一样,如果你的编译器有提示,你可以看它的函数原型,然后网上找用法

我觉得你离你的目标好像有点愚公移山的感觉
2014-08-29 09:47
cr945211
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2014-7-31
收藏
得分:0 
回复 19 楼 天使梦魔
因为我基础太差所以给你的这种感觉吧?
   我倒是满怀希望的,总感觉解决现在这个问题以后就好办了,一点点把那些命令功能加上去就行了吧。以你的了解,有什么办法把“山”搬得快一点吧?或者说,难点在哪里,我得怎么下苦工?
   匿名通道的问题,我是在网上找别人做的例子然后通过分析知道它的作用,所以好多问题都不确定。。
2014-08-29 10:50
快速回复:在 VS 下调用 MinGW 做个自己的编译器 IDE,该方案是否可行?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018073 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved