2013-07-19 77 views
0

我是编程新手,并且遇到使用串行API接口synclink适配器的示例c代码问题。使用C++编译c时链接错误

我想用C++编译器(Visual Studio C++ 2010)编译C源文件。我更改了C++编译器的设置,将项目编译为C(在项目属性页 - > C/C++ - > advanced下),并且包含其他目录mghdlc.h和链接mghdlc.lib(在链接器 - >附加库目录)。代码如下:

#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; 
} 

,但我得到了以下错误:

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 [email protected] referenced in function _get_port_id 
1>testing.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _main 
1>testing.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _main 
1>testing.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _main 
1>testing.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _main 
1>testing.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _main 
1>testing.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _main 
1>testing.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _main 
1>testing.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _main 
1>testing.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _main 
1>c:\users\jjteo\documents\visual studio 2010\Projects\testing\Debug\testing.exe : fatal error LNK1120: 10 unresolved externals 

==========生成:0成功,1失败,0上TO-日期,0跳过==========

使用C++编译器编译c代码是否导致问题?我该如何解决。谢谢。

+1

这些是链接器错误,而不是编译器错误,和[看到这个问题。](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-如何解决这个问题 – chris

+0

为了详细说明,我特别想知道如何解决LNK2019错误。这是额外的包含目录的问题吗? – user2598476

+2

它们不是编译错误,而是链接错误。您需要链接到提供_Mgsl方法的库。 – mkirci

回答

1

显然你已经获得了SyncLink API的头文件,但是你并没有引用它的库文件(.LIB)。

检入API目录中的任何.LIB文件并将它们添加到编译器链接选项中。如果您使用的是Visual Studio,那么在项目属性的链接器部分会有一个名为“Addition Libraries”的部分(我认为)。可能有一些.LIB文件已列在那里,所以请尝试添加SyncLink。

+0

嗨。我已经在项目属性 - >链接器 - >常规 - >附加库目录下添加了额外的库(mghdlc.lib)。我还在项目属性 - > C/C++ - >附加包含目录下添加了include头文件(mghdlc.h)。 – user2598476

+0

“额外的库目录”设置告诉编译器何时查找,但你必须告诉它寻找什么。您可以这样做:在链接器设置中指定.LIB或在代码中使用#pragma。 – Sean

+0

感谢您的所有帮助。但是,我如何在链接器设置中指定.LIB?在链接器选项下,只有“附加库目录”。 – user2598476

0

在Linker-> Input-> Additional Dependencies中设置mghdlc.lib,包括调试版本和发布版本。或者在源代码中添加代码“#pragma comment(lib,”mghdlc.lib“)”“。

您还必须确定您的mghdlc.lib文件在“其他库目录”设置的路径中是正确的。