Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> драйвер com-порта для erlang 
:(
    Опции темы
Bulat
Дата 15.2.2013, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: нет
Всего: 57



Всем добрый день.

Есть необходимость в написании драйвера для работы с com-портом на erlang. OC - windows XP.

В интернете нашел я нечто похожее. Я плохо знаю С, но все же малость подхачив найденный мною исходник уткнулся в две последние проблемы на этапе компиляции

Код

[Linker error] undefined reference to `SecureZeroMemory'
[Linker error] undefined reference to `WinMain@16'
ld returned 1 exit status 


оригинал исходников выглядиит следующим образом

gen_serial.c :

Код

#include <assert.h>
#include <erl_driver.h>
#include <stdio.h>
#include <memory.h>
#define WIN32_LEAN_AND_MEAN 
#include <windows.h>

#define CODE_OK 0x80
#define CODE_CANT_OPEN 0xA0
#define CODE_CANT_WRITE 0xA1
#define CODE_CANT_READ 0xA2
#define CODE_BADARG 0xFF

typedef struct {
    ErlDrvPort port;
        HANDLE hComm;
} DriverData;

static HANDLE connect( char* buffer, int bufflen )
{
        HANDLE hComm;
        DCB dcb = {0};
        COMMTIMEOUTS timeouts;
        unsigned comm_port;
        unsigned baud_rate;
        unsigned data_bits;
        unsigned parity;
        unsigned stop_bits;
        unsigned flow_control;
        wchar_t comm_port_str[8];

        assert( bufflen == 7 );

        comm_port = buffer[0];
        baud_rate = (buffer[1]<<8) + buffer[2];
        data_bits = buffer[3];
        parity = buffer[4];
        stop_bits = buffer[5];
        flow_control = buffer[6];

        wsprintf( comm_port_str, L"COM%u", comm_port );
        hComm = CreateFile( comm_port_str,  
                GENERIC_READ | GENERIC_WRITE, 
                0, 0, 
                OPEN_EXISTING,
                0, 0);
        if (hComm == INVALID_HANDLE_VALUE) return hComm;

        SecureZeroMemory(&dcb, sizeof(DCB));
        dcb.DCBlength = sizeof(DCB);
        if ( !GetCommState(hComm, &dcb) ) {
                CloseHandle( hComm );
                return INVALID_HANDLE_VALUE;
        }
        dcb.BaudRate = (baud_rate==0) ? 110 : (unsigned long)baud_rate * 300;
        dcb.fParity = TRUE;
        dcb.ByteSize = data_bits;
        dcb.Parity = parity;
        dcb.StopBits = ONESTOPBIT;
        dcb.fOutxCtsFlow = FALSE;
        dcb.fRtsControl = RTS_CONTROL_DISABLE;
        dcb.fOutxDsrFlow = FALSE;
        dcb.fDtrControl = DTR_CONTROL_DISABLE;
        dcb.fInX = FALSE;
        dcb.fOutX = FALSE;
        switch ( flow_control ) {
                default:
                case 0: // No flow control
                        // Already in default state
                        break;
                case 1: // RTS/CTS control
                        dcb.fOutxCtsFlow = TRUE;
                        dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
                        break;
                case 2: // DTR/DSR control
                        dcb.fOutxDsrFlow = TRUE;
                        dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
                        break;
                case 3: // Xon/Xoff control
                        dcb.fInX = TRUE;
                        dcb.fOutX = TRUE;
                        break;
        }
        if ( !SetCommState(hComm, &dcb) ) {
                CloseHandle( hComm );
                return INVALID_HANDLE_VALUE;
        }

        if ( !GetCommTimeouts( hComm, &timeouts ) ) {
                CloseHandle( hComm );
                return INVALID_HANDLE_VALUE;
        }
        timeouts.ReadIntervalTimeout = MAXDWORD; 
        timeouts.ReadTotalTimeoutMultiplier = 0;
        timeouts.ReadTotalTimeoutConstant = 0;
        timeouts.WriteTotalTimeoutMultiplier = 0;
        timeouts.WriteTotalTimeoutConstant = 0;
        if ( !SetCommTimeouts(hComm, &timeouts) ) {
                CloseHandle( hComm );
                return INVALID_HANDLE_VALUE;
        }

        if ( !SetCommMask( hComm, EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY ) ) {
                CloseHandle( hComm );
                return INVALID_HANDLE_VALUE;
        }

        return hComm;
}

static ErlDrvData gen_serial_start(ErlDrvPort port, char *buff)
{
    DriverData* data = (DriverData*)driver_alloc( sizeof(DriverData) );
        if ( !data ) return ERL_DRV_ERROR_GENERAL;

    data->port = port;
        data->hComm = INVALID_HANDLE_VALUE;
    return (ErlDrvData)data;
}

static void gen_serial_stop(ErlDrvData handle)
{
        DriverData* data = (DriverData*)handle;

        assert( handle );
        assert( data );

        if ( data->hComm != INVALID_HANDLE_VALUE )
                CloseHandle( data->hComm );
    driver_free( (char*)handle );
}

static void gen_serial_output(ErlDrvData const drv_data, char *buff, int bufflen)
{
        DriverData* const data = (DriverData*)drv_data;
        DWORD written = 0;
        BOOL flag;
        char msg = CODE_OK;

        assert( drv_data );
        assert( data );
        assert( buff );
        assert( bufflen > 0 );

        flag = WriteFile( data->hComm, buff, bufflen, &written, NULL );
        if ( !flag || written != bufflen ) msg = CODE_CANT_WRITE;
        driver_output( data->port, &msg, 1 );
}

static int gen_serial_control( ErlDrvData drv_data, unsigned int command, 
        char *buf, int len, char **rbuf, int rlen )
{
        DriverData* const data = (DriverData*)drv_data;
        DWORD written;
        BOOL flag;

        static char msg_80[] = "\x80"; /* Ok */
        static char msg_a0[] = "\xA0"; /* Could not open port */
        static char msg_a1[] = "\xA1"; /* Error sending data */
        static char msg_a2[] = "\xA2"; /* Error reading data */
        static char msg_fe[] = "\xFE"; /* Invalid format for message */
        static char msg_ff[] = "\xFF"; /* Unrecognized message */

        assert( drv_data );
        assert( data );
        assert( rbuf );
        assert( rlen > 0 );

        switch ( command ) {
                case 1: /* connect */
                        if ( len != 7 ) {
                                *rbuf[0] = CODE_BADARG;
                                return 1;
                        }
                        else {
                                HANDLE hComm = connect( buf, len );
                                if ( hComm == INVALID_HANDLE_VALUE ) {
                                        *rbuf[0] = CODE_CANT_OPEN;
                                        return 1;
                                }
                                else {
                                        data->hComm = hComm;
                                        *rbuf[0] = CODE_OK;
                                        return 1;
                                }
                        }
                        return 0;

                case 3: /* recv */
                        written = 0;
                        *rbuf[0] = CODE_OK;
                        flag = ReadFile( data->hComm, (*rbuf)+1, rlen-1, &written, NULL );
                        if ( !flag ) {
                                *rbuf[0] = CODE_CANT_READ;
                                return 1;
                        }
                        return written + 1;

                case 4: /* recv length */
                        if ( len != 4 ) {
                                *rbuf[0] = CODE_BADARG;
                                return 1;
                        }
                        written = (((DWORD)buf[0])<<24) + (((DWORD)buf[1])<<16) + (((DWORD)buf[2])<<8) + buf[3];
                        if ( written > rlen-1 ) written = rlen-1;
                        *rbuf[0] = CODE_OK;
                        flag = ReadFile( data->hComm, (*rbuf)+1, written, &written, NULL );
                        if ( !flag ) {
                                *rbuf[0] = CODE_CANT_READ;
                                return 1;
                        }
                        return written + 1;

                default: /* error */
                        *rbuf[0] = CODE_BADARG;
                        return 1;
                        return 0;
        }
}

ErlDrvEntry driver_entry = {
    NULL,                                       /* F_PTR init, N/A */
    gen_serial_start,           /* L_PTR start, called when port is opened */
    gen_serial_stop,            /* F_PTR stop, called when port is closed */
    gen_serial_output,          /* F_PTR output, called when erlang has sent */
    NULL,                                       /* F_PTR ready_input, called when input descriptor ready */
    NULL,                                       /* F_PTR ready_output, called when output descriptor ready */
    "gen_serial",                       /* char *driver_name, the argument to open_port */
        NULL,                                   /* F_PTR finish, called when unloaded */
        NULL,                                   /* handle */
        gen_serial_control,             /* F_PTR control, port_command callback */
        NULL,                                   /* F_PTR timeout, reserved */
        NULL                                    /* F_PTR outputv, reserved */
};

DRIVER_INIT(gen_serial)         /* must match name in driver_entry */
{
    return &driver_entry;
}


dllmain.c :

Код

#define WIN32_LEAN_AND_MEAN 
#include <windows.h>

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                                         )
{
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
                break;
        }
        return TRUE;
}


Если кто-нибудь мне поможет разобраться в чем тут дело - буду очень признателен


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
bsa
Дата 15.2.2013, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



скорее всего, ты пытаешься собрать программу как GUI application. А надо как DLL.
PM   Вверх
Dem_max
Дата 16.2.2013, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Если честно ну код совсем не похож на драйвер


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
fish9370
Дата 16.2.2013, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: -1
Всего: 1



Цитата(Bulat @  15.2.2013,  17:32 Найти цитируемый пост)
[Linker error] undefined reference to `SecureZeroMemory'


замени на memset, здесь SecureZeroMemory - какая-то внешнаяя функци, которая безопасно обнуляет память..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
Bulat
Дата 16.2.2013, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: нет
Всего: 57



Цитата(bsa @  15.2.2013,  23:33 Найти цитируемый пост)
скорее всего, ты пытаешься собрать программу как GUI application. А надо как DLL. 

возможно...


Цитата(fish9370 @  16.2.2013,  11:27 Найти цитируемый пост)
замени на memset, здесь SecureZeroMemory - какая-то внешнаяя функци, которая безопасно обнуляет память.. 

где?



Цитата(Bulat @  15.2.2013,  17:32 Найти цитируемый пост)
Я плохо знаю С


Поэтому можно чуть поподробнее. =)



--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
fish9370
Дата 16.2.2013, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: -1
Всего: 1



выкинуть: SecureZeroMemory(&dcb, sizeof(DCB));

вставить: memset(&dcb, 0, sizeof(DCB));


--------------------
undefined
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0770 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.