문제

I'm new to programming, and am having problems with a sample c code for to interface a synclink adapter using serial API.

I am trying to compile a C source file with C++ compiler (Visual Studio C++ 2010). I've changed the settings for the C++ compiler to compile the project as C (under project property pages -> C/C++ -> advanced), and included the additional directory mghdlc.h and link mghdlc.lib (under linker -> additional library directories). The code is as follows:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <windows.h>
#include <errno.h>

#include <mghdlc.h>

int get_port_id(char *name)
{
unsigned long i, rc, count;
int port_id = 0;
PMGSL_PORT ports;


/* get count of available ports */
rc = MgslEnumeratePorts(NULL, 0, &count);
if (rc != NO_ERROR) {
    printf("MgslEnumeratePorts() error=%d\n", rc);
    return 0;
}

if (!count)
    return 0;

/* allocate memory to hold port information */
ports = malloc(count * sizeof(MGSL_PORT));
if (ports == NULL) {
    printf("memory allocation failed\n");
    return 0;
}

/* get port information */
rc = MgslEnumeratePorts(ports, count * sizeof(MGSL_PORT), &count);
if (rc != NO_ERROR) {
    printf("MgslEnumeratePorts() error=%d\n", rc);
    goto done;
}

/* search for entry with matching name */
for (i=0; i < count; i++) {
    if (!_stricmp(ports[i].DeviceName, name)) {
        port_id = ports[i].PortID;
        break;
    }
}

done:
free(ports);
return port_id;
}

int stop_program = 0;

void sigint_handler(int sigid)
{
stop_program = 1;
}

int main(int argc, char **argv)
{
int port_id;
HANDLE fd;
FILE *fp;
DWORD rc;
int databuf_size;
int count;
int written;
OVERLAPPED ol;
MGSL_RECEIVE_REQUEST *rx_req;
MGSL_PARAMS params;

if (argc < 2) {
    printf("\nYou must specify device name as argument.\n"
           "Examples:\n"
           "C:>receive-raw MGMP4P2  (adapter #4 port #2 of multiport adapter)\n"
           "C:>receive-raw MGHDLC1  (single port adapter adapter #1)\n"
           "Available device names can be viewed in the SyncLink branch\n"
           "of the Windows device manager.\n\n");
    return 1;
}

printf("receive raw data on %s\n", argv[1]);

/* convert device name to port ID */
port_id = get_port_id(argv[1]);
if (port_id == 0) {
    printf("No such port %s\n", argv[1]);
    return 1;
}

/* open device */
rc = MgslOpen(port_id, &fd);
if (rc != NO_ERROR) {
    printf("MgslOpen error=%d\n", rc);
    return rc;
}

/* open file to store received data */
fp = fopen("data", "wb");
if (fp == NULL) {
    printf("fopen error=%d %s\n", errno, strerror(errno));
    return errno;
}

//#define SET_BASE_CLOCK 1  
#ifdef SET_BASE_CLOCK
/*
 * Set base clock frequency if custom hardware base clock installed.
 *
 * Use only if a base clock different than the standard 14745600
 * is installed at the factory. The driver uses this value to
 * calculate data clock rates which are derived from the base clock.
 */
rc = MgslSetOption(fd, MGSL_OPT_CLOCK_BASE_FREQ, 25000000);
if (rc != NO_ERROR)
    printf("MgslSetOption(MGSL_OPT_CLOCK_BASE_FREQ) error=%d\n", rc);
#endif

/* get current device parameters */
rc = MgslGetParams(fd, &params);
if (rc != NO_ERROR) {
    printf("MgslGetParams() error=%d\n", rc);
    return rc;
}

/*
 * configure port for raw synchronous mode
 * loopback disabled
 * receiver clock source = RxC clock input
 * transmit clock source = TxC clock input
 * encoding = NRZ
 * output clock on AUXCLK output at 19200 bps
 * disable ITU/CCITT CRC-16 frame checking (not supported in raw mode)
 */
params.Mode = MGSL_MODE_RAW;
params.Loopback = 0;
params.Flags = HDLC_FLAG_RXC_RXCPIN + HDLC_FLAG_TXC_TXCPIN;
params.Encoding = HDLC_ENCODING_NRZ;
params.ClockSpeed = 19200;
params.CrcType = HDLC_CRC_NONE;

/* set current device parameters */
rc = MgslSetParams(fd, &params);
if (rc != NO_ERROR) {
    printf("MgslSetParams() error=%d\n", rc);
    return rc;
}

/* set transmit idle pattern */
rc = MgslSetIdleMode(fd, HDLC_TXIDLE_ONES);
if (rc != NO_ERROR)
    printf("MgslSetIdleMode() error=%d", rc);

printf("Turn on RTS and DTR serial outputs\n");
rc = MgslSetSerialSignals(fd, SerialSignal_RTS + SerialSignal_DTR);
if (rc != NO_ERROR)
    printf("assert DTR/RTS error=%d\n", rc);

/* MgslReceive requires OVERLAPPED structure and event */
ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (ol.hEvent == NULL) {
    printf("CreateEvent error = %d\n", GetLastError());
    return 1;
}

/* MgslReceive needs MGSL_RECEIVE_REQUEST structure (header + data buffer) */
databuf_size = 128;
rx_req = malloc(sizeof(MGSL_RECEIVE_REQUEST) + databuf_size);
if (rx_req == NULL) {
    printf("can't allocate receive request structure\n");
    return 1;
}

MgslEnableReceiver(fd, 1); /* enable receiver */

signal(SIGINT, sigint_handler);
printf("press Ctrl-C to stop program\n");

while (!stop_program) {

    /* prepare for MgslReceive call */
    rx_req->DataLength = databuf_size;
    ResetEvent(ol.hEvent);

    rc = MgslReceive(fd, rx_req, &ol);

    if (rc == ERROR_IO_PENDING) {
        printf("wait for received data...");
        while (!stop_program) {
            rc = WaitForSingleObject(ol.hEvent, 100); 
            if (rc == WAIT_OBJECT_0)
                break; /* receive request complete */
            if (rc != WAIT_TIMEOUT) {
                printf("WaitForSingleObject error = %d\n",      GetLastError());
                return rc;
            }
        }
        if (stop_program) {
            printf("Ctrl-C pressed, cancel receive request\n");
            MgslCancelReceive(fd);
            break;
        }
    } else if (rc != NO_ERROR) {
        printf("MgslReceive error=%d\n", rc);
        return rc;
    }

    /* process completed receive request */

    if (rx_req->Status == RxStatus_OK) {
        count = rx_req->DataLength;
        printf("received %d bytes\n", count);
        /* write received data to file */
        written = (int)fwrite(rx_req->DataBuffer, sizeof(char), count, fp);
        if (written != count)
            printf("fwrite error=%d %s\n", errno, strerror(errno));
        fflush(fp);
    } else
        printf("receive error, status = %d\n", rx_req->Status);
}

MgslEnableReceiver(fd, 0); /* disable receiver */

printf("Turn off RTS and DTR ser`enter code here`ial outputs\n");
rc = MgslSetSerialSignals(fd, 0);
if (rc != NO_ERROR)
    printf("turn off DTR/RTS error=%d\n", rc);

MgslClose(fd); /* close device */
fclose(fp); /* close output file */

return 0;
}

But i get the following errors:

1>------ Build started: Project: testing, Configuration: Debug Win32 ------
1>  testing.cpp
1>c:\users\jjteo\documents\visual studio    2010\projects\testing\testing\testing.cpp(124): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdio.h(234) : see declaration of 'fopen'
1>c:\users\jjteo\documents\visual studio 2010\projects\testing\testing\testing.cpp(126): warning C4996: 'strerror': This function or variable may be unsafe. Consider using strerror_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string.h(157) : see declaration of 'strerror'
1>c:\users\jjteo\documents\visual studio 2010\projects\testing\testing\testing.cpp(241): warning C4996: 'strerror': This function or variable may be unsafe. Consider using strerror_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
 1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string.h(157) : see declaration of 'strerror'
 1>testing.obj : error LNK2019: unresolved external symbol _MgslEnumeratePorts@12 referenced in function _get_port_id
 1>testing.obj : error LNK2019: unresolved external symbol _MgslClose@4 referenced in function _main
 1>testing.obj : error LNK2019: unresolved external symbol _MgslCancelReceive@4 referenced in function _main
 1>testing.obj : error LNK2019: unresolved external symbol _MgslReceive@12 referenced in function _main
 1>testing.obj : error LNK2019: unresolved external symbol _MgslEnableReceiver@8 referenced in function _main
 1>testing.obj : error LNK2019: unresolved external symbol _MgslSetSerialSignals@8 referenced in function _main
 1>testing.obj : error LNK2019: unresolved external symbol _MgslSetIdleMode@8 referenced in function _main
 1>testing.obj : error LNK2019: unresolved external symbol _MgslSetParams@8 referenced in function _main
 1>testing.obj : error LNK2019: unresolved external symbol _MgslGetParams@8 referenced in function _main
 1>testing.obj : error LNK2019: unresolved external symbol _MgslOpen@8 referenced in function _main
 1>c:\users\jjteo\documents\visual studio 2010\Projects\testing\Debug\testing.exe : fatal error LNK1120: 10 unresolved externals

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Are the problems caused by compiling c code with the C++ compiler? How do I fix this. Thanks.

도움이 되었습니까?

해결책

You've obviously got the header file for SyncLink API, but you're not referencing the library file (.LIB) that goes with it.

Check in the API directory for any .LIB files and add them to your compilers link options. If you're using Visual Studio then there will be a section called "Addition Libraries" (I think) in the linker section of the project properties. There are probably some .LIB files listed there already, so try adding the one for SyncLink.

다른 팁

Set mghdlc.lib in Linker->Input-> Additional Dependencies, both debug and release version. Or add code “#pragma comment(lib, "mghdlc.lib")” in your source code.

You also have to be sure that your mghdlc.lib file is right int the path that "additional library directories" sets.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top