初次使用vs2010基于c 开发项目碰到的问题及解决方法-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 16836
  • 博文数量: 10
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 12
  • 用 户 组: 普通用户
  • 注册时间: 2015-06-18 00:48
文章分类

(10)

  • (10)
文章存档

(10)

我的朋友
相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: windows

2015-07-29 08:19:07

原文地址: 作者:

1、将过去的工程用vs2010打开的时候。你有可能会遇到一大堆的警告:warning c4996。
比如:warning c4996: 'sprintf': this function or variable may be unsafe. consider using sprintf_s instead. to disable deprecation, use _crt_secure_no_warnings.
原因是visual c 2005使用了更加安全的run-time library routines。
新的security crt functions(就是那些带有“_s”后缀的函数):

那么如何搞定这些警告呢:

原因解释
这种微软的警告,主要因为那些c库的函数,很多函数内部是不进行参数检测的(包括越界类的),微软担心使用这些会造成内存异常,所以就改写了同样功能的函数,改写了的函数进行了参数的检测,使用这些新的函数会更安全和便捷。关于这些改写的函数你不用专门去记忆,因为编译器对于每个函数在给出警告时,都会告诉你相应的安全函数,查看警告信息就可以获知,在使用时也再查看一下msdn详细了解。库函数改写例子:
mkdir改写为 _mkdir
fopen”改写为 fopen_s
stricmp改写为 stricmp_s
sprintf改写为sprintf_s

strcpy改写为strcpy_s

    凯发app官方网站的解决方案:
1> 根据下面的warning提示:参见“fopen”的声明
        消息:“this function or variable may be unsafe. consider using fopen_s instead. to disable deprecation, use _crt_secure_no_deprecate. see online help for details.”
        所以可以将函数按warning提示的第二句,改为使用fopen_s函数即可:
        例如:file *pfile=fopen("1.txt", "w");
           改为:
           file* pfile;
           fopen_s(&pfile, "1.txt", "w");
2> 还是根据warning提示的地三句话:use _crt_secure_no_deprecate
        项目|属性|配置属性|c/c |命令行|附加选项,加入【/d "_crt_secure_no_deprecate" 】(注:加入中括号中完整的内容)
3> 降低警告级别:项目|属性|配置属性|c/c |常规,自己根据情况降低警告级别(此法不推荐)
    注意:高度重视警告:使用编译器的最高警告级别。应该要求构建是干净利落的(没有警告)。理解所有警告。通过 修改代码而不是降低警告级别来排除警告。

方法一:手工将原来的旧函数替换成新的security crt functions。
方法二:屏蔽这个警告。
            在预编译头文件stdafx.h里(注意:一定要在没有include任何头文件之前)定义下面的宏:
            #define _crt_secure_no_deprecate
            或者#param warning(disable:4996)
方法二没有使用新的更安全的crt函数,显然不是一个值得推荐的方法,可是你又不想一个一个地改。
那么还有一个更方便的方法:
在预编译头文件stdafx.h里(同样要在没有include任何头文件之前)定义下面的宏:
#define _crt_secure_cpp_overload_standard_names 1
在链接的时候便会自动将旧函数替换成security crt functions。
注意:这个方法虽然使用了新的函数,但是不能消除警告你还得同时使用方法二。。。

2、serialport收数据时出现的bugcomstat is being used without defining

比如:run-time check failure #3 - the variable 'comstat' is being used without being initialized.

cserialport类在visual c .net 应用时会出现意想不到的问题。以《visual c /turobo c串口通信编程实践》(龚建伟 熊光明 著)一书中第二章的serialporttest程序为例,当在visual c .net下编写后之后,debug之后,会出现编译错误:“operator ="不明确,msdn解释“为重载运算符定
义了多个可能的运算符。可能的凯发app官方网站的解决方案:对一个或多个实际参数使用显式转换。”当将

long cserialporttestdlg::oncomm(wparam ch, lparam port)
{
m_streditreceivemsg =ch;
updatedata(false); //将接收到的字符显示在接收编辑框中
return 0;
}

中m_streditreceivemsg =ch;改写为m_streditreceivemsg =char(ch);后,debug顺利通过了。其实这个还不是cserialport类的问题。m_streditreceivemsg =ch;改写为m_streditreceivemsg =char(ch) 是应该的,这样更为严谨,因为在 oncomm(wparam ch, lparam port)函数中,ch 为 wparam 型数据,wparam型数据适应型很强,char(ch)将ch强制转换为char型,更适合cstring型,这应该算是vc.net的进步。

    当将这个问题解决之后,编译成功了。然后开始测试。向串口调试助手发送消息时一切正常。但从串口调试助手向serialporttest发送消息时,报错了,说“comstat is being used without defining",在serialport.cpp中,可以找到comstat的定义:comstat comstat; 但将光标指向comstat时右键转到定义处或声明处,却均提示“未定义符号”,这便是cserialport类在vc.net应用中的问题了。那该如何解决这个问题呢?在这,我们向大家提供两种凯发app官方网站的解决方案:

方案1: 改变项目配置属性

    一种凯发app官方网站的解决方案是改变基本运行时检查(changing the runtime checks in project settings):在菜单project->project properties-> c/c -> code generation-> basic runtime checks --> change to 'default',在中文版中是:项目-〉属性-〉配置属性-〉c/c 代码生成-〉基本运行时检查-〉设置为默认,当将基本运行时检查改为默认之后,编译自然顺利通过了,向串口调试助手发送消息正常了,再从串口调试助手向serialporttest发送消息时,也正常了。

方案2:改变comstat变量属性

     另一种凯发app官方网站的解决方案是将cserialport.cpp中的comstat comstat;改为static comstat comstat;这样改了之后,debug顺利通过,然后调试,与串口调试助手相互发消息都ok了。为什么这样就能解决呢?其实当你使用debug凯发app官方网站的解决方案时,它的基本运行时检查初始设置为:两者(/rtc1,等同于 /rtcsu),这个两者是指:堆栈帧(/rtcs),未初始化的变量(/rtcu)。由于它要检查未初始化的变量,所以将serialport.cpp中的comstat comstat;改为static comstat comstat;就可以正常使用cserialport类了。
     以上是在debug下的凯发app官方网站的解决方案,当在release编译状态时,你会发现并不需要将comstat comstat;改为static comstat comstat;就能编译成功并且发送接收消息正常。其实,在release下,它的基本运行时检查初始设置已为默认。这应该也算是第一种凯发app官方网站的解决方案之内。
    而当你将它设置为两者(/rtc1,等同于 /rtcsu)时,不论是否将comstat comstat;改为static comstat comstat;,编译都不能通过,报错““cl.exe”返回的结果有误。",这个应该是属于release的问题了,另当别论了。

3、c 连接mysql

1)、新建一个工程,随便写一个helloworld,目的是就是让工程下的“debug”文件夹出现
2)、把d:\program files\mysql\mysql server 5.5\lib下面的libmysql.dll复制到工程的debug文件夹里面
3)、接下来要设置一些引用文件的环境变量,首先,点击项目->属性->vc 目录。
然后“include目录”那把“d:\program files\mysql\mysql server 5.5\include”给加进来
再然后“lib目录”那里把“d:\program files\mysql\mysql server 5.5\lib”也一起加进来

vc6.0设置:

(1)打开vc6.0 工具栏tools菜单下的options选项,在directories的标签页中右边的“show directories for:”下拉列表中选中“includefiles”,然后在中间列表框中添加你本地安装mysql的include目录路径。(我的是d:\program files\mysql\mysql server 5.5\include)。

(2)在上面说到的“show directories for:”下拉列表中选中“library files”,然后添加你本地安装mysql的lib目录路径。lib目录下有debug目录,选debug。(我的是d:\program files\mysql\mysql server 5.5\lib\debug)。

4)、然后在项目->属性窗口下点击:连接器->输入->附加依赖项,把"libmysql.lib"写进去

vc6.0设置:在“project settings->link:object/library modules”里面添加“libmysql.lib”。

使用vc 编译时再添加以下项:

5)、在stdafx.h里面添加如下的内容:
#include "mysql.h"

#include "winsock.h" // 如果编译出错,则把该行放到#include "mysql.h"之前#pragma comment(lib,"libmysql.lib") // 如果在附加依赖项里已增加,则就不要添加了

3.1

1>test.obj : error lnk2019: 无法解析的外部符号 ,该符号在函数 _main 中被引用
1>test.obj : error lnk2019: 无法解析的外部符号 ,该符号在函数 _main 中被引用
1>test.obj : error lnk2019: 无法解析的外部符号 ,该符号在函数 _main 中被引用
1>test.obj : error lnk2019: 无法解析的外部符号 ,该符号在函数 _main 中被引用
1>test.obj : error lnk2019: 无法解析的外部符号 ,该符号在函数 _main 中被引用
1>test.obj : error lnk2019: 无法解析的外部符号 ,该符号在函数 _main 中被引用
1>test.obj : error lnk2019: 无法解析的外部符号 ,该符号在函数 _main 中被引用
1>d:\program_files\c&c \test_mysql\debug\test_mysql.exe : fatal error lnk1120: 7 个无法解析的外部命令

此异常是没有在项目属性的连接器中的“附加依赖项”中添加libmysql.dll。

 

3.2 编译正常,运行的时候报错:无法启动此程序,因为计算机中丢失libmysql.dll。尝试重新安装该程序解决此问题。

此问题是因为没有将解压后的mysql目录下lib/debug(opt)中的libmysql.dll拷贝到工程目录下(或debug目录中)。

 

3.3

1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(291): error c2146: 语法错误: 缺少“;”(在标识符“fd”的前面)
1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(291): error c4430: 缺少类型说明符 - 假定为 int。注意: c 不支持默认 int
1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(291): error c4430: 缺少类型说明符 - 假定为 int。注意: c 不支持默认 int
1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(470): error c2065: “socket”: 未声明的标识符
1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(470): error c2146: 语法错误: 缺少“)”(在标识符“s”的前面)
1>c:\program files\mysql\mysql server 5.5\include\mysql_com.h(471): error c2059: 语法错误:“)”

上述错误原因要结合编译环境来解决。

1)windows.h头文件必须放在mysql.h之前;

2)在vs2008中,若已经执行了第一步却仍然不行,检查mysql.h之前是否有如下代码:

#define win32_lean_and_mean             // 从 windows 头中排除极少使用的资料

上述语句通常在stdafx.h中。删掉该句即可。

 

3.4

>正在链接...
1>stdafx.obj : error lnk2005: "public: struct st_mysql_res * __thiscall dbutil::resultset(char *)" () 已经在 prethread.obj 中定义
1>stdafx.obj : error lnk2005: "public: __thiscall dbutil::~dbutil(void)" () 已经在 prethread.obj 中定义
1>stdafx.obj : error lnk2005: "public: void __thiscall dbutil::init(void)" () 已经在 prethread.obj 中定义
1>stdafx.obj : error lnk2005: "public: __thiscall dbutil::dbutil(char *,char *,char *,char *)" () 已经在 prethread.obj 中定义
1>stdafx.obj : error lnk2005: "public: __thiscall dbutil::dbutil(void)" () 已经在 prethread.obj 中定义
1>d:\program_files\multi-core\xoj_acs\release\xoj_acs.exe : fatal error lnk1169: 找到一个或多个多重定义的符号

头文件被重复包含

4.“messageboxw”: 不能将参数 2 从“const char [1]”转换为“lpcwstr”

(部分摘自:)

因为你的程序在unicode(宽字节)字符集下运行,如果调用了 messagebox ,实际上调用的是 messageboxw 函数;
如果你的程序在 ansi 字符集运行,调用 messagebox ,就相当于调用 messageboxa;
其中 messageboxw 支持 unicode;
messageboxa 支持ansi;
unicode与ansi 有什么区别呢?简单的说,unicode版的字符比ansi 的内存占用大,比如:
win32程式中出现的标准定义 char 占一个字节,
而 char 的unicode版被定义成这样:
typedef unsigned short wchar_t ;占2个字节。
所以有字符做参数的函数相应也用两个版本了。
宽字节版函数中带有字符参数的都应该用宽字节版的字符参数,将字符串转换成宽字节很容易:
比如将 "application error" 转换成unicode版,只需在它前面使用一个定义了的宏,如下:
l"application error" ,或者text("application error" )都可以
所以你应将 messagebox(null,temp,"application error",mb_iconstop); 改为:
          messagebox(null,temp,l"application error",mb_iconstop);

5、fatal error lnk1107: 文件无效或损坏: 无法在 0x278 处读取

该问题可能是引入的库不正确,但是经过查看,引入的文件以及库均正确,仅仅是删除了项目属性,连接器中的“附加依赖项”中的值,本项试试删除该项是否会导致程序无法运行,结果显示这个错误。等再次加上的时候,依然无效,索性将所有引入的文件以及库均删除,全部重新添加,问题解决。

6、 编译正常,运行的时候报错:"0x0041596d" 指令引用的"0x00000000"内存。该内存不能为"written"。
错误原因:这是指针结构没初始化,而引用产生的地址错误
如下:
char *hostname = "localhost";
char *username = "root";
char *pass = "111";//你的mysql服务器密码
char *dbname = "mysql";
unsigned int port = 3306; //server port 
struct database_param *mysql_param;//没有初始化就引用了
struct data_param *db_param;  //没有初始化就引用了

int main()
{

 cdatabase mysqldb;

 mysql_param->host = hostname;
 mysql_param->user = username;
 mysql_param->password =pass;
 mysql_param->db = dbname;
 mysql_param->port = 3306;
 //mysql_param->unix_socket,null;
 mysql_param->client_flag = 0;
 //mysql_param = &db_param;
 db_param->db_name = mysql_param->db;


修改后:
char *hostname = "localhost";
char *username = "root";
char *pass = "111";//你的mysql服务器密码
char *dbname = "mysql";
unsigned int port = 3306; //server port 
struct database_param *mysql_param;
struct data_param *db_param;

int main()
{

 cdatabase mysqldb;

 mysql_param = new (struct database_param );//对指针先初始化后引用
 db_param = new (struct data_param);

 mysql_param->host = hostname;
 mysql_param->user = username;
 mysql_param->password =pass;
 mysql_param->db = dbname;
 mysql_param->port = 3306;
 //mysql_param->unix_socket,null;
 mysql_param->client_flag = 0;
 //mysql_param = &db_param;
 db_param->db_name = mysql_param->db;

7、error c2593: “operator =”不明确 

处理串口输入事件时

afx_msg lresult cserialportptestdlg::oncomm(wparam wparam, lparam lparam)
{
 m_streditreceivemsg = wparam;
 updatedata(false);  //将接收到的字符显示在接收编辑框中
 return 0;
 return 0;
}

编译时出现“operator   =”不明确,也就是m_streditreceivemsg = wparam;
改正方法:

        m_streditreceivemsg = (char)wparam;,因为系统里面存在一个wchar_t的类型,所以如果支持了这个类型的话,从unsigned nt转换到wchar_t和char的等级都是标准转换,所以编译器无法判断到底应该转换到哪一个,故而导致了这个问题。

1>i:\prj\commterm\commterm\serial\serialport.cpp(23): error c2664: “createfilew”: 不能将参数 1 从“const char *”转换为“lpcwstr”
1>          与指向的类型无关;转换要求 reinterpret_cast、c 样式转换或函数样式转换

点击项目->属性->配置属性->常规
然后“字符集”那把“使用 unicode 字符集”改为“未设置”或“使用多字节字符集”
再然后“lib目录”那里把“d:\program files\mysql\mysql server 5.5\lib”也一起加进来

 

#include "stdafx.h"
#include
如果颠倒了,就会出现下面一堆令人头疼的错误:

正在编译...
servertest.cpp
e:\project c \servertest\servertest\servertest\servertest.cpp(58) : error c2146: 语法错误 : 缺少“;”(在标识符“hservstatus”的前面)
e:\project c \servertest\servertest\servertest\servertest.cpp(58) : error c2501: “hservstatus” : 缺少存储类或类型说明符
e:\project c \servertest\servertest\servertest\servertest.cpp(59) : error c2146: 语法错误 : 缺少“;”(在标识符“hsstat”的前面)
e:\project c \servertest\servertest\servertest\servertest.cpp(59) : error c2501: “hsstat” : 缺少存储类或类型说明符
e:\project c \servertest\servertest\servertest\servertest.cpp(75) : error c2065: “service_table_entry” : 未声明的标识符
e:\project c \servertest\servertest\servertest\servertest.cpp(75) : error c2146: 语法错误 : 缺少“;”(在标识符“dispatchtable”的前面)

 

在控制台下写程序
控制台下用windows api写比较好。用这个类型:critical_section g_cs;
然后 initializecriticalsection(...)
   entercriticalsection(...);
   leavecriticalsection(...);

  critical_section m_sec;
  initializecriticalsection( &m_sec );
  deletecriticalsection( &m_sec );
  entercriticalsection( &m_sec );
  leavecriticalsection( &m_sec );
 

阅读(1130) | 评论(0) | 转发(0) |
0

上一篇:

下一篇:

给主人留下些什么吧!~~
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图