C++中的文件包含问题,请大侠指教!UP有分!解决的话,分数多多!
我做的一个小程序,用来连接mySQL数据库,用到其中的C API,同样的包含方式在一个C文件中通过,可是在这个C++文件中不能通过,编译时出现错误:
file.cpp:
#include <tchar.h>
#include <time.h>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include "my_utility.h" //<<--mySQL要用到的头文件
#include "Serial.h"
#define INTERVAL 3
...
SQLHDBC hdbc;
SQLHSTMT hstmt;
rc = SQLExecDirect(hstmt,command,SQL_NTS); //《〈————
...
my_utility.h文件如下,都是从它的例子中拿出来的:
#ifndef __TMYODBC_UTILITY_H__
#define __TMYODBC_UTILITY_H__
#ifdef HAVE_CONFIG_H
#include <myconf.h>
#endif
#ifdef WIN32
#include <windows.h>
#endif
/* STANDARD C HEADERS */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/* ODBC HEADERS */
#include <sql.h>
#include <sqlext.h>
#ifndef NULL
#define NULL 0
#endif
#ifndef ushort
#define ushort unsigned short
#endif
#ifndef bool
#define bool unsigned char
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#define MAX_NAME_LEN 95
#define MAX_COLUMNS 255
#define MAX_ROW_DATA_LEN 255
SQLCHAR *mydsn = "myodbc3-test"; ////<<--
SQLCHAR *myuid = "develop"; ////<<--
SQLCHAR *mypwd = "bbmf00"; ////<<--
/* PROTOTYPE */
void myerror(SQLRETURN rc,SQLSMALLINT htype, SQLHANDLE handle);
/* UTILITY MACROS */
#define myenv(henv,r) \
if ( ((r) != SQL_SUCCESS) ) \
myerror(r, 1,henv); \
assert( ((r) == SQL_SUCCESS) || ((r) == SQL_SUCCESS_WITH_INFO) )
#define myenv_err(henv,r,rc) \
if ( rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO ) \
myerror(rc, 1, henv); \
assert( r )
#define mycon(hdbc,r) \
if ( ((r) != SQL_SUCCESS) ) \
myerror(r, 2, hdbc); \
assert( ((r) == SQL_SUCCESS) || ((r) == SQL_SUCCESS_WITH_INFO) )
#define mycon_err(hdbc,r,rc) \
if ( rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO ) \
myerror(rc, 2, hdbc); \
assert( r )
#define mystmt(hstmt,r) \
if ( ((r) != SQL_SUCCESS) ) \
myerror(r, 3, hstmt); \
assert( ((r) == SQL_SUCCESS) || ((r) == SQL_SUCCESS_WITH_INFO) )
#define mystmt_err(hstmt,r,rc) \
if ( rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO ) \
myerror(rc, 3, hstmt); \
assert( r )
/********************************************************
* MyODBC 3.51 error handler *
*********************************************************/
void myerror(SQLRETURN rc, SQLSMALLINT htype, SQLHANDLE handle)
{
SQLRETURN lrc;
if( rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO )
{
SQLCHAR szSqlState[6],szErrorMsg[SQL_MAX_MESSAGE_LENGTH];
SQLINTEGER pfNativeError;
SQLSMALLINT pcbErrorMsg;
lrc = SQLGetDiagRec(htype, handle,1,
(SQLCHAR *)&szSqlState,
(SQLINTEGER *)&pfNativeError,
(SQLCHAR *)&szErrorMsg,
SQL_MAX_MESSAGE_LENGTH-1,
(SQLSMALLINT *)&pcbErrorMsg);
if(lrc == SQL_SUCCESS || lrc == SQL_SUCCESS_WITH_INFO)
printf("\n [%s][%d:%s]\n",szSqlState,pfNativeError,szErrorMsg);
}
}
/********************************************************
* MyODBC 3.51 connection handler *
*********************************************************/
void myconnect(SQLHENV *henv,SQLHDBC *hdbc, SQLHSTMT *hstmt)
{
SQLRETURN rc;
printf("\nmyconnect:\n");
rc = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,henv);
myenv(*henv,rc);
rc = SQLSetEnvAttr(*henv,SQL_ATTR_ODBC_VERSION,(SQLPOINTER)SQL_OV_ODBC3,0);
myenv(*henv,rc);
rc = SQLAllocHandle(SQL_HANDLE_DBC,*henv, hdbc);
myenv(*henv,rc);
printf(" connecting to '%s' with user name '%s'...\n",mydsn,myuid);
rc = SQLConnect(*hdbc, mydsn, SQL_NTS, myuid, SQL_NTS, mypwd, SQL_NTS);
mycon(*hdbc,rc);
rc = SQLSetConnectAttr(*hdbc,SQL_ATTR_AUTOCOMMIT,(SQLPOINTER)SQL_AUTOCOMMIT_ON,0);
mycon(*hdbc,rc);
rc = SQLAllocHandle(SQL_HANDLE_STMT,*hdbc,hstmt);
mycon(*hdbc,rc);
printf(" success!!\n");
}
/********************************************************
* MyODBC 3.51 closes the connection *
*********************************************************/
void mydisconnect(SQLHENV *henv,SQLHDBC *hdbc, SQLHSTMT *hstmt)
{
SQLRETURN rc;
printf("\nmydisconnect:\n");
rc = SQLFreeStmt(*hstmt, SQL_DROP);
mystmt(*hstmt,rc);
rc = SQLDisconnect(*hdbc);
mycon(*hdbc,rc);
rc = SQLFreeConnect(*hdbc);
mycon(*hdbc,rc);
rc = SQLFreeEnv(*henv);
myenv(*henv,rc);
printf(" success!!\n");
}
#endif /* __TMYODBC_UTILITY_H__ */
编译错误为:
d:\develop\testsm\my_utility.h(68) : error C2440: “初始化” : 无法从“char [13]”转换为“SQLCHAR *”
与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换
d:\develop\testsm\my_utility.h(69) : error C2440: “初始化” : 无法从“char [8]”转换为“SQLCHAR *”
与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换
d:\develop\testsm\my_utility.h(70) : error C2440: “初始化” : 无法从“char [7]”转换为“SQLCHAR *”
与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换
d:\develop\testsm\testsm.cpp(108) : error C2664: “SQLExecDirect” : 不能将参数 2 从“char [400]”转换为“SQLCHAR *”
与指向的类型无关;转换要求 reinterpret_cast、C 样式转换或函数样式转换
请高手帮帮忙,看看是怎么回事。环境:2000+VS2003
同样的程序结构在C中就没问题,
问题点数:100、回复次数:21Top
1 楼ross33123()回复于 2003-12-02 04:39:03 得分 40
C++ 中类型比 C 严格,这里出现的错误是要求你显式转换。
mydsn, myuid, mypwd应写成
SQLCHAR *mydsn = (SQLCHAR *)"myodbc3-test"; ////<<--
SQLCHAR *myuid = (SQLCHAR *)"develop"; ////<<--
SQLCHAR *mypwd = (SQLCHAR *)"bbmf00"; ////<<--
Top
2 楼liuguangzhou(光子)回复于 2003-12-02 05:16:59 得分 0
的确是行家!敬佩!我加了显式转换后,可以编译了,可是链接时候又出错了.在没有加入上面这个头文件的时候是没有这些链接错误的.请大侠再帮忙看看,感激不尽阿!
Serial.lib(Serial.obj) : warning LNK4218: 找到非本机模块;用 /LTCG 重新启动链接
LINK : warning LNK4075: 忽略“/INCREMENTAL”(由于“/LTCG”规范)
LINK : warning LNK4098: 默认库“LIBC”与其他库的使用冲突;使用 /NODEFAULTLIB:library
testsm.obj : error LNK2001: 无法解析的外部符号 "public: unsigned char __thiscall CSerial::GetRLSD(void)" (?GetRLSD@CSerial@@QAEEXZ)
testsm.obj : error LNK2001: 无法解析的外部符号 "public: unsigned char __thiscall CSerial::GetDSR(void)" (?GetDSR@CSerial@@QAEEXZ)
testsm.obj : error LNK2001: 无法解析的外部符号 "public: unsigned char __thiscall CSerial::GetCTS(void)" (?GetCTS@CSerial@@QAEEXZ)
testsm.obj : error LNK2001: 无法解析的外部符号 "public: virtual long __thiscall CSerial::Open(char const *,unsigned long,unsigned long,unsigned char)" (?Open@CSerial@@UAEJPBDKKE@Z)
Debug/testsm.exe : fatal error LNK1120: 4 个无法解析的外部命令
编译命令行是:
/Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Gm /EHsc /RTC1 /MT /Fo"Debug/" /Fd"Debug/vc70.pdb" /W3 /nologo /c /Wp64 /ZI /TP
/MT /D "_X86_" /c
链接命令行是:
/OUT:"Debug/testsm.exe" /INCREMENTAL /NOLOGO /DEBUG /PDB:"Debug/testsm.pdb" /SUBSYSTEM:CONSOLE /MACHINE:IX86 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.libTop
3 楼xyfsky(飞天)回复于 2003-12-02 08:10:52 得分 2
UPTop
4 楼mfc168(子非鱼)回复于 2003-12-02 08:32:19 得分 7
缺少了一个静态库,该静态库包含函数GetRLSD,GetCTS等Top
5 楼crusaderg(刻苦)回复于 2003-12-02 08:35:56 得分 2
upTop
6 楼liuleilover(Vietor)回复于 2003-12-02 08:39:35 得分 2
upTop
7 楼fingerfox(狐狸【人不要脸,天下无敌】)回复于 2003-12-02 08:42:31 得分 7
CSerial类的几个函数没有实现.Top
8 楼nkwesley(江南丝竹)回复于 2003-12-02 08:42:44 得分 2
呵呵,有点帮助,UP一下Top
9 楼yintongshun(左岸思雨)回复于 2003-12-02 08:57:23 得分 7
楼上的都说了,出现无法解析的外部符号一般是缺少库文件或者在stdafx.h中缺少必要的定义声明Top
10 楼dreamy(如何敲开MS的大门?)回复于 2003-12-02 09:02:17 得分 7
把包含CSerial::GetRLSD等函数的lib文件加入到你的Linker中或者把文件直接加入工程即可Top
11 楼derryzhang(雨田)回复于 2003-12-02 10:52:32 得分 2
学习ing,Up一下^_^Top
12 楼farfh(阿远之哈儿)回复于 2003-12-02 11:19:24 得分 7
差一个cpp或者lib连接Top
13 楼liuleilover(Vietor)回复于 2003-12-02 11:22:11 得分 2
学习ing,Up一下^_^
Top
14 楼liuguangzhou(光子)回复于 2003-12-02 12:04:49 得分 0
我使用的是一个包装COM的lib,它的cpp和h文件都有,编译输出了一个静态库。我把它加进我的工程里,对应的文件都包含了,就是那个
#include "Serial.h"
库文件是Serial.lib
在静态库的工程中有上面链接中出错的几个函数的声明和定义。并且我把库文件从工程中拿掉,影响不大,但是注释掉#include "Serial.h"时,出现更多的链接错误,都是和Serial.lib有关的,但是,后来出现的东西和已开始出现的链接错误中的函数都在同一个文件中Serial.h/Serial.cpp,不明白为什么,请高手指点!!Top
15 楼liuguangzhou(光子)回复于 2003-12-02 12:19:49 得分 0
我在链接选项里加入了附加依赖项,加入Serial.lib
链接命令行为:
/OUT:"Debug/testsm.exe" /INCREMENTAL /NOLOGO /DEBUG /PDB:"Debug/testsm.pdb" /SUBSYSTEM:CONSOLE /MACHINE:IX86 Serial.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Serial.lib
依然是同样的链接错误.请指点Top
16 楼ross33123()回复于 2003-12-02 12:41:10 得分 2
出现这种情况应该是这个 lib 不能被 VC 的 link.exe 使用。
请查阅文档,看有没有for VC的库的版本。Top
17 楼wangweixing2000(星(inspiration(灵感)))回复于 2003-12-02 12:41:23 得分 2
gzTop
18 楼ross33123()回复于 2003-12-02 12:46:39 得分 0
原来lib是你自己做的阿。。。。。。
是用VC做的吗?做的时候有没有发现什警告?
Top
19 楼wpmsoft(红旗下的蛋)回复于 2003-12-02 13:34:27 得分 7
哈哈
与LIB一起的还有DLL,它呢?是否放到了你的搜索路径下??
我LIB中只有声明及函数的地址索引,没有实现的BODY呀。
不对之处,请高手指正。Top
20 楼fuxf(布衣)回复于 2003-12-02 13:46:26 得分 2
upTop
21 楼liuguangzhou(光子)回复于 2003-12-02 14:37:10 得分 0
问题解决了,解决方法令人啼笑皆非,只是include的顺序不对.结贴了.可惜了我昨天晚上的时间了!
file.cpp:
#include <tchar.h>
#include <time.h>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include "my_utility.h" //<<--mySQL要用到的头文件
#include "Serial.h" //<<--放在这里,链接出错
#define INTERVAL 3
file.cpp:
#include <tchar.h>
#include <time.h>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include "Serial.h" //<<--放在这里,OK!
#include "my_utility.h" //<<--mySQL要用到的头文件
#define INTERVAL 3Top




