1. 苏葳的备忘录首页
  2. 开发工具

把一个nmake工程移到VS2010集成环境中的一些问题

visual studio nmake自.net时代之后,就没怎么用过VC了。这几天想把一个nmake的dll工程放进vs2010集成环境里,还真费了不少工夫。此工程是从微软例程里下载的一个dll例子,大约是为VC6准备的。但是在vs2010环境下,执行过vcvars32.bat后,直接nmake此工程的makefile文件即成功。然后regsvr32什么的都没有问题。当然在win8的vs2013下就有点问题,主要是该项目的makefile包含的win32.mak的路径问题,也可能是新版windows sdk的问题,此问题微软有解释,这里暂且不提。

由于希望用集成环境开发调试,所以要把这工程移入Visual studio 2010。此工程目录包含cpp/h文件,资源文件,def文件,ico/jpg等。还有重要的makefile文件。那么,首先想到的就是,有没有工具将makefile转化为dsw/dsp文件呢?

网上找找,还真有一个perl做的工具,按说明使用,成功生成了dsw/dsp文件。这时才愣过来,vs2010集成环境早已不用dsw/dsp格式工程文件了。那么双击这个dsw打开,看能自动转换新版不?结果也确实转换成新版的sln/suo文件了,但却是空的,显然这跨度有点太大了。

查找微软文档,提到这种情况可使用Makefile Project Wizard ,这是个什么东西?按提示在vs2010的项目创建模板里死活找不到。最后才灵光一闪,莫非那个“生成文件项目”就是这东西?打开一看,果然如此。翻译害死人啊。

那就创建个”生成文件项目“,到了设置项目属性一步,一大堆命令行要填写之类,也没耐心去研究了。直接在”生成命令行“地方填上”nmake”,在清理命令行填上”nmake clean”。尝试编译一下,居然生成成功了。当然。。这跟用直接用nmake生成是没区别的,生成的dll不是放在vs默认的debug目录下,而是放在makefile默认的win2000_debug目录下(此vs2010装在xp虚拟机下,makefile引用的系统win32.mak指定了默认输出目录)。

那么还是老实的创建个正经的win32空dll项目,手工把相关文件加进去试试吧。

创建个win32工程,选dll,选空项目(不然就会有带预编译头文件stdafx.h的空dll框架代码)。然后将所有相关项目文件,都拷入新项目文件夹下。然后,分别在源文件中加入所有cpp文件,在头文件中加入所有h文件,在资源文件中加入rc文件。生成一下试试。还好,除了些宏重复定义的警告外,只有4个错误,都是TCHAR *不能转化成char *之类。原来用makefile生成时,宏重复的警告也有,不用管它,那么这个TCHAR *到char *转化之类的错误怎么办呢?

在代码中出错的地方,用(char *)这样的强制类型转换,好了这个错误跳过去了。但总觉不靠谱,未修改过的代码用makefile 怎么就能nmake过去呢?查看文档,TCHAR在有#define UNICODE定义时是双字节字符,没有时就是单字节。显然跟这个有关。查看项目属性里,c/c++树下的命令行里,果然有/D _UNICODE和/D UNICODE选项。如何去掉呢?在预处理器里,取消预处理器定义里,把_UNICODE;UNICODE加上,再生成,虽有警告,但提示生成功了。再找找有没其它办法,在常规一栏里,把字符集从unicode改为”未设置””。好,去掉“取消预处理器定义”里刚才加的东西。查看命令行的参数里,也没有unicode相关的定义了。再生成,成功,没有错误了。

既然生成了,去查看源码下的debug目录里,却没有生成的dll文件,但看里面的项目名称.log,里面显示项目名称.dll确实是生成了啊?怎么回事呢?找了半天,发现原来生成的dll并不放在这个debug里,这里的都是一些中间文件,生成的dll是放在与源码目录平级的一个debug目录 下。。。

现在dll是生成了,但regsvr32注册时,却找不到注册入口。原来的makefile项目是有def文件的,那么def文件也拷过来了,怎么用上这个def文件呢?

在项目属性的“链接器”中,找到个高级:入口点,是不是这里呢?不确定。再找,在“链接器->输入”一栏里,找到了“模块定义文件”,把def文件名输进去(注意,若生成dll文件名与def文件中的dll文件名不同,需修改),再重新生成。然后regsvr32 xxx.dll,成功,regsvr32 /u xxx.dll,也成功。试验dll功能,正常。OK,算是迁移成功了。

在xp虚拟机中的vs2010生成dll之后,拷至win7 64位版host机中用regsvr32注册时,却报错:模块xxxx.dll加载失败,请确保该二进制存储在指定路径中或者调试它以检查该二进制或相关的.dll文件是否有问题。找不到指定的模块。

用regsvr32在管理员权限命令行窗口执行,无效,尝试安装vc2010 x64运行库,无效。再尝试将其拷入syswow64目录下注册,也无效。regasm命令用于注册.net 程序集,应该也不能用于此处。暂不查找问题原因。将项目拷至在win7 64位下,用安装的vs2013编译测试下看结果如何。

拷过去的工程与vs2010中的项目配置基本相同。但编译时报了C4996错误。查找联机文档:

“为了支持新的、更安全的函数,否决了某些 CRT 和标准 C++ 库函数。 有关要改用的函数的更多信息,请参见错误消息中被否决的函数的文档。 _CRT_SECURE_NO_WARNINGS.” xml:space=””preserve”>若要关闭 CRT 否决警告,请定义 _CRT_SECURE_NO_WARNINGS。 Security Features in the CRT and Safe Libraries: C++ Standard Library.’ xml:space=”preserve”>有关不推荐使用的函数的更多信息,请参见 CRT 中的安全功能和安全库:C++ 标准库。

在项目属性的c/c++->预处理器定义中,加上_CRT_SECURE_NO_WARNINGS,注意分号分隔。重新生成,成功。regsvr32 注册之,也成功。

原创文章,作者:苏葳,如需转载,请注明出处:https://www.swmemo.com/575.html

发表评论

邮箱地址不会被公开。 必填项已用*标注

评论列表(6条)