• [编译] 2、minGW gcc在windows搭建编译win32程序环境



    1、普通下载一个MinGW程序、安装之后可以直接将MinGW目录拷贝到总工程的tool里面:

     demo_mesh_common tree -L 2
    .
    ├── app
    ├── bin
    ├── build
    ├── doc
    ├── sdk
    │   ├── alg
    │   ├── bsp
    │   ├── driver
    │   └── phy
    └── tool
        └── MinGW
    


    2、参考学习在dos下使用gcc来编译,发现分步骤编译会报_alloca未定义的错误:

    a.o:a.c:(.text+0x3f8): undefined reference to `_alloca'
    

    猜测可能是有些库没有链接进来,于是搜索MinGW/lib/下的库:

    F:demo_mesh_common	oolMinGWlib>grep -rn "_alloc"
    Binary file libmingw32.a matches
    Binary file libmingwex.a matches
    Binary file libwldap32.a matches
    Binary file libdxerr8.a matches
    Binary file libdxerr9.a matches
    Binary file gcc/mingw32/3.4.5/libgcc.a matches
    Binary file librpcdce4.a matches
    Binary file libbfd.a matches
    Binary file libiberty.a matches
    

    通过一个一个加进编译选项,最终发现:需要将gcc/mingw32/3.4.5/libgcc.a加入:

    ./MinGW/bin/ld -L"./MinGW/lib" -o a.exe a.o  "./MinGW/lib/crt2.o" -lmingw32 -lkernel32 -lmsvcrt -luser32 -lwow32 -lwldap32 -lwin32k -lvfw32 -lmingw32 -lmingwex -lwldap32 -ldxerr8 -ldxerr9 -lrpcdce4 -lbfd -liberty -L"./MinGW/lib/gcc/mingw32/3.4.5" -lgcc
    


    3、我测试的win32串口程序,在Git Bush(linux属性)的窗口中可以执行,但无数据,必须在win窗口中执行。


    4、附录

    makefile:

    a.o:a.c
    	./MinGW/bin/gcc -c a.c
    B:a.o
    	./MinGW/bin/ld -L"./MinGW/lib" -o a.exe a.o  "./MinGW/lib/crt2.o" -lmingw32 -lkernel32 -lmsvcrt -luser32 -lwow32 -lwldap32 -lwin32k -lvfw32 -lmingw32 -lmingwex -lwldap32 -ldxerr8 -ldxerr9 -lrpcdce4 -lbfd -liberty -L"./MinGW/lib/gcc/mingw32/3.4.5" -lgcc
    
    
    A:
    	./MinGW/bin/gcc -s -O2 a.c -mconsole
    

    a.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <string.h>
    #include <malloc.h>
    
    HANDLE hComm;
    OVERLAPPED m_ov;
    COMSTAT comstat;
    DWORD    m_dwCommEvents;
    
    
    //如果在调用CreateFile创建句柄时指
    //定了FILE_FLAG_OVERLAPPED标志,那么调用ReadFile和WriteFile对该句柄进
    //行的操作就应该是重叠的;如果未指定
    //重叠标志,则读写操作应该是同步的
    //在同步执行时,函数直到操作完成后才返回。这意味着同步执行时线程会被阻塞,从
    //而导致效率下降。在重叠执行时,即使操作还未完成,这两个函数也会立即返回,费
    //时的I/O操作在后台进行
    BOOL openport(char *portname)//打开一个串口
    {
        hComm = CreateFile(portname,
    	GENERIC_READ | GENERIC_WRITE,
    	0,
    	0,
    	OPEN_EXISTING,
    	FILE_FLAG_OVERLAPPED,    
    	0);
        if (hComm == INVALID_HANDLE_VALUE)
    	return FALSE;
        else
    	return TRUE;
    }
    
    
    BOOL setupdcb(int rate_arg)
    {
        DCB  dcb;
        int rate= rate_arg;
        memset(&dcb,0,sizeof(dcb)); //在一段内存块中填充某个给定的值,是对较大的结构//体或数组进行清零操作的一种最快方法
        if(!GetCommState(hComm,&dcb))//获取当前DCB配置
        {
    	return FALSE;
        }
        /* -------------------------------------------------------------------- */
        // set DCB to configure the serial port
        dcb.DCBlength       = sizeof(dcb);
        /* ---------- Serial Port Config ------- */
        dcb.BaudRate        = rate;
        dcb.Parity      = NOPARITY;
        dcb.fParity     = 0;
        dcb.StopBits        = ONESTOPBIT;
        dcb.ByteSize        = 8;
        dcb.fOutxCtsFlow    = 0;
        dcb.fOutxDsrFlow    = 0;
        dcb.fDtrControl     = DTR_CONTROL_DISABLE;
        dcb.fDsrSensitivity = 0;
        dcb.fRtsControl     = RTS_CONTROL_DISABLE;
        dcb.fOutX           = 0;
        dcb.fInX            = 0;
        /* ----------------- misc parameters ----- */
        dcb.fErrorChar      = 0;
        dcb.fBinary         = 1;
        dcb.fNull           = 0;
        dcb.fAbortOnError   = 0;
        dcb.wReserved       = 0;
        dcb.XonLim          = 2;
        dcb.XoffLim         = 4;
        dcb.XonChar         = 0x13;
        dcb.XoffChar        = 0x19;
        dcb.EvtChar         = 0;
        /* -------------------------------------------------------------------- */
        // set DCB
        if(!SetCommState(hComm,&dcb))
        {
    	return FALSE;
        }
        else
    	return TRUE;
    }
    //在用readfile和writefile读写串行口时,需要考虑超时问题, 读写串口的超时有两
    //种:间隔超时和总超时, 写操作只支持总超时,而读操作两种超时均支持, 如果所有
    //写超时参数均为0,那么就不使用写超时。
    BOOL setuptimeout(DWORD ReadInterval,DWORD ReadTotalMultiplier,DWORD ReadTotalconstant,DWORD WriteTotalMultiplier,DWORD WriteTotalconstant)               
    {
        COMMTIMEOUTS timeouts;
        timeouts.ReadIntervalTimeout=ReadInterval; //读间隔超时
        timeouts.ReadTotalTimeoutConstant=ReadTotalconstant; //读时间系数
        timeouts.ReadTotalTimeoutMultiplier=ReadTotalMultiplier; //读时间常量
        timeouts.WriteTotalTimeoutConstant=WriteTotalconstant; // 写时间系数
        timeouts.WriteTotalTimeoutMultiplier=WriteTotalMultiplier; //写时间常//量, 总超时的计算公式是:总超时=时间系数×要求读/写的字符数+时间常量
        if(!SetCommTimeouts(hComm, &timeouts))
        {
    	return FALSE;
        }
        else
    	return TRUE;
    }
    void ReceiveChar(){
        BOOL  bRead = TRUE;
        BOOL  bResult = TRUE;
        DWORD dwError = 0;
        DWORD BytesRead = 0;
        char RXBuff;
        while(TRUE){
    	bResult = ClearCommError(hComm, &dwError, &comstat);
    	// 在使用ReadFile 函数进行读操作前,应先使用ClearCommError函数清除错误
    	if(comstat.cbInQue==0)// COMSTAT结构返回串口状态信息
    	    //本文只用到了cbInQue成员变量,该成员变量的值代表输入缓冲区的字节数
    	    continue;
    	if(bRead){
    	    bResult = ReadFile(hComm, // Handle to COMM port串口的句柄
    	        &RXBuff,// RX Buffer Pointer// 读入的数据存储的地址,即读入的数据将存//储在以该指针的值为首地址的一片内存区
    	        1,// Read one byte要读入的数据的字节数,
    	        &BytesRead, // Stores number of bytes read, 指向一个DWORD//数值,该数值返回读操作实际读入的字节数
    	        &m_ov);           // pointer to the m_ov structure// 重叠操作时,该参数指向一个OVERLAPPED结构,同步操作时,该参数为NULL
    	    printf("%02X",RXBuff);
    	    if (!bResult){// 当ReadFile和WriteFile返回FALSE时,不一定就是操作失//败,线程应该调用GetLastError函数分析返回的结果
    	        switch (dwError = GetLastError()){
    	        case ERROR_IO_PENDING:
    	                bRead = FALSE;
    	                break;
    	        default:break;
    	        }
    	    }else{
    	        bRead = TRUE;
    	    }
    	}  // close if (bRead)
    	if (!bRead){
    	    bRead = TRUE;
    	    bResult = GetOverlappedResult(hComm,    // Handle to COMM port
    	        &m_ov,    // Overlapped structure
    	        &BytesRead,        // Stores number of bytes read
    	        TRUE);             // Wait flag
    	}
        }
    }
    BOOL WriteChar(BYTE* m_szWriteBuffer,DWORD m_nToSend){
        BOOL bWrite = TRUE;
        BOOL bResult = TRUE;
        DWORD BytesSent = 0;
        HANDLE    m_hWriteEvent;
        ResetEvent(m_hWriteEvent);
        if (bWrite){
    	m_ov.Offset = 0;
    	m_ov.OffsetHigh = 0;
    	// Clear buffer
    	bResult = WriteFile(hComm,    // Handle to COMM Port, 串口的句柄
    	    m_szWriteBuffer,        // Pointer to message buffer in calling finction
    	                            // 即以该指针的值为首地址的nNumberOfBytesToWrite
    	                            // 个字节的数据将要写入串口的发送数据缓冲区
    	    m_nToSend,                // Length of message to send, 要写入的数据的字节数
    	    &BytesSent,                // Where to store the number of bytes sent
    	                            // 指向指向一个DWORD数值,该数值返回实际写入的字节数
    	    &m_ov );                // Overlapped structure
    	                            // 重叠操作时,该参数指向一个OVERLAPPED结构,
    	                            // 同步操作时,该参数为NULL
    	if (!bResult){                // 当ReadFile和WriteFile返回FALSE时,不一定就是操作失
    	    //败,线程应该调用GetLastError函数分析返回的结果
    	    DWORD dwError = GetLastError();
    	    switch (dwError){
    	    case ERROR_IO_PENDING: //GetLastError函数返回//ERROR_IO_PENDING。这说明重叠操作还未完成
    	            // continue to GetOverlappedResults()
    	            BytesSent = 0;
    	            bWrite = FALSE;
    	            break;
    	    default:break;
    	    }
    	}
        } // end if(bWrite)
        if (!bWrite){
    	bWrite = TRUE;
    	bResult = GetOverlappedResult(hComm,    // Handle to COMM port
    	    &m_ov,        // Overlapped structure
    	    &BytesSent,        // Stores number of bytes sent
    	    TRUE);             // Wait flag
    	
    	// deal with the error code
    	if (!bResult){
    	    printf("GetOverlappedResults() in WriteFile()");
    	}
        } // end if (!bWrite)
        
        // Verify that the data size send equals what we tried to send
        if (BytesSent != m_nToSend){
    	printf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d
    ", BytesSent, strlen((char*)m_szWriteBuffer));
        }
        return TRUE;
    }
    
    int main(void){
    	printf("open comport successsdsfds
    ");
        if(openport("com3"))
    	printf("open comport success
    ");
        if(setupdcb(9600))
    	printf("setupDCB success
    ");
        if(setuptimeout(0,0,0,0,0)) //如果所有写超时参数均为0,那么就不使用写超时
    	printf("setuptimeout success
    ");
        PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); // 在读写串口之前,还要用PurgeComm()函数清空缓冲区
        //PURGE_TXABORT      中断所有写操作并立即返回,即使写操作还没有完成。
        //PURGE_RXABORT      中断所有读操作并立即返回,即使读操作还没有完成。
        //PURGE_TXCLEAR      清除输出缓冲区
        //PURGE_RXCLEAR      清除输入缓冲区
        //WriteChar("please send data now",20);
        printf("received data:
    ");
        ReceiveChar( );
        system("pause");
    
    	return 0;
    }
    

    链接

    @beautifulzzzz
    智能硬件、物联网,热爱技术,关注产品
    博客:http://blog.beautifulzzzz.com
    园友交流群:414948975
    
  • 相关阅读:
    文本转换成音频流
    把文本以图片的形式保存
    list集合绑定在datagridview上时如何实现排序
    厘米转换成像素
    sql经典语句收集
    存储过程加密
    跨服务器sql操作
    lvs(+keepalived)、haproxy(+heartbeat)、nginx 负载均衡的比较分析
    [Big Data]Hadoop详解一
    CDN技术详解及实现原理
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/9157295.html
Copyright © 2020-2023  润新知