[原创]在linux系统中编写windows程序并连接成二进制文件

软件和网站开发以及相关技术探讨
回复
skycn
帖子: 30
注册时间: 2006-06-05 23:27

[原创]在linux系统中编写windows程序并连接成二进制文件

#1

帖子 skycn » 2007-12-15 6:58

相信大家对linux的开发环境都很满意,但windows下的应用软件实在是太多了,而且市场决定程序员如果有开发windows软件的经验就更有竞争力,如果你必须在windows环境下开发但又不喜欢windows,现在我有一个办法可以让你在linux下像写linux程序一样写windows程序。

1. 安装wine,为了可以在linux平台上执行windows程序,这个就不说了,源里有,直接装就好了

2. 在windows平台上安装Visual Studio C++ 6.0 (个人比较喜欢6.0,因为小,而且还有MFC)

以下步骤要在linux内操作:

3. 拷贝c:\Program Files\Micro$oft Vi$ual $tudio 文件夹到 $HOME/.wine/drive_c/Program Files/
ok, 现在你有VC了,但你不能用,IDE也不能用,不知道为什么,不过不管了, 反正我并不喜欢VS的IDE。在$HOME/.wine/drive_c/Program Files/Micro$oft Vi$ual $tudio/VC98/Bin 这个文件夹里有一个文件: cl.exe
注意这个文件,它其实是和linux 的gcc 或 g++ 是一样的,是个编译器。虽然找到这个编译器了,但如果我们用它编译程序的话,它会保错,原因是:
在Windows系统中,有三个系统变量:PATH,LIB,INCLUDE, 这三个系统变量对应于 编译器所在文件夹,库文件夹,和头文件夹。
大家都知道windows有个东西叫注册表吧,gnome也有类似的东西,wine是可以直接编辑注册表的,因为它把注册表分为了几个部分,其中CURRENT_USER这个部分被存放在 $HOME/.wine/drive_c/user.reg 中,好了,有办法注册系统变量了。

vim ~/.wine/driver_c/user.reg

然后把下面的内容复制进去,哪里都可以:

[Environment] 1197666624
"Basemake"="C:\\Program Files\\Microsoft Platform SDK\\Include\\BKOffice.Mak\\"
"Bkoffice"="C:\\Program Files\\Microsoft Platform SDK\\"
"INCLUDE"="C:\\Program Files\\Microsoft Platform SDK\\Include\\.;C:\\Program Files\\Microsoft Visual Studio\\VC98\\Atl\\Include;C:\\Program Files\\Microsoft Visual Studio\\VC98\\mfc\\include;C:\\Program Files\\Microsoft Visual Studio\\VC98\\include\\"
"INETSDK"="C:\\Program Files\\Microsoft Platform SDK\\"
"LIB"="C:\\Program Files\\Microsoft Platform SDK\\Lib\\.;C:\\Program Files\\Microsoft Visual Studio\\VC98\\mfc\\lib;C:\\Program Files\\Microsoft Visual Studio\\VC98\\lib\\"
"MSDevDir"="C:\\Program Files\\Microsoft Visual Studio\\Common\\MSDev98\\"
"MSSdk"="C:\\Program Files\\Microsoft Platform SDK\\"
"Mstools"="C:\\Program Files\\Microsoft Platform SDK\\"
"PATH"="C:\\Program Files\\Microsoft Visual Studio\\Common\\Tools\\WinNT;C:\\Program Files\\Microsoft Visual Studio\\Common\\MSDev98\\Bin;C:\\Program Files\\Microsoft Visual Studio\\Common\\Tools;C:\\Program Files\\Microsoft Visual Studio\\VC98\\bin;C:\\Program Files\\Microsoft Platform SDK\\Bin\\.;C:\\Program Files\\Microsoft Platform SDK\\Bin\\WinNT\\Y"


红色的部分比较重要,指明了编译器所在目录已经库文件和头文件
做完上面这些后,你已经可以正常的编译WIN32程序了

代码: 全选

wine cl test.cpp
但如果想编译MFC程序还需要作些小修改, 因为所有的MFC程序都是默认多线程模式执行的,而当我们用cl编译程序时,默认是单线程的,所以,会给一个错误:

代码: 全选

nafxcw.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
nafxcw.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
要解决这个错误,只需在cl选项内把默认的线程模型置为多线程

代码: 全选

wine test.cpp /MT
但还是会有一个错误:

代码: 全选

libc.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
这是由于cl编译的程序默认是命令行模式,而MFC程序是窗口模式,只需改变link的参数即可:
(这里解释一下,cl的原理跟gcc相同,是编译和link一起做了)

代码: 全选

wine cl test.cpp /MT /link /subsystem:windows
这就没问题了,程序正常编译,并连接为 test.exe,试一下

代码: 全选

wine test.exe
这样只是解决了MFC程序的编译,至于ATL和COM库的连接是否会出现问题,还有待发现。下面给一小段MFC程序供测试

代码: 全选

#include "AFXWIN.H"

class MFC_Tutorial_Window :public CFrameWnd
{
public:
    MFC_Tutorial_Window()
    {
         Create(NULL,"MFC Tutorial Part 1 CoderSource Window");
    }
};

class MyApp :public CWinApp
{
   MFC_Tutorial_Window *wnd; 
public:
   BOOL InitInstance()
   {
        wnd = new MFC_Tutorial_Window();
        m_pMainWnd = wnd;
        m_pMainWnd->ShowWindow(1);
        return 1;
     }
};

MyApp theApp;
4. 最后一步,捷径
写一个script , 让cl用起来像gcc或g++一样

sudo vim /usr/bin/cl
写入

代码: 全选

#!/bin/bash
#
file="$*"
#ar="user32.lib gdi32.lib odbc32.lib nafxcw.lib libc.lib LIBCMT.LIB MSVCRT.LIB"
ar="/MT /link /subsystem:windows"

if [ $file!=null ]; then
	wine cl $file $ar
else
	wine cl
fi
然后 sudo chmod a+x cl

这样,你在编译windows程序时,只需执行
cl test.cpp 就OK了



欢迎补充
头像
mikeandmore
帖子: 109
注册时间: 2005-10-13 18:29

#2

帖子 mikeandmore » 2007-12-15 20:31

没啥技术含量和意义。。。
首先。VC6是淘汰产品。。。不合你自己的逻辑
其次,我还以为是mingw作cross compile要是那样的话就有点技术含量了。。。因为嵌入式设备大多是cross compile的,所以意义还是比较大。
最后,市场决定产品,但是现在Linux Desktop才是市场的新区域,你是愿意随波逐流,去更危险的竞争还是动动脑筋另辟蹊径,是你个人的竞争风格了。。。
头像
mikeandmore
帖子: 109
注册时间: 2005-10-13 18:29

#3

帖子 mikeandmore » 2007-12-15 20:33

不过还是支持原创的。。。
现在的中国IT。。。没有多少像lz这样的原创者了。。。。
头像
stlxv
论坛版主
帖子: 8275
注册时间: 2006-05-03 0:39
来自: المريخ

#4

帖子 stlxv » 2007-12-15 21:53

用fpc直接编译,连wine都不用了
PHP是最好的语言!不服来战!
skycn
帖子: 30
注册时间: 2006-06-05 23:27

#5

帖子 skycn » 2007-12-15 22:04

干什么都需要基础,我不懂楼上说的嵌入式compiler是何道理
好像python是这类东西,但python的缺点是,它只是script
但我觉得做什么还是要从开始做起,若是还没把基础的东西搞明白,就去弄高级的东西,那就真成了钳工了
还没学会写程序,就搞嵌入式开发,起点太高了吧
MFC是不再开发了,但作为类库还是很优秀的,我对微软后来的东西都不很喜欢,但MFC很适合学习用,API的包装类,很基础,只是被VC弄的有点神秘了,其实它和wxWidget是同出一类

Linux Desktop是新区域,但我觉得似乎不是主流吧,小部分人的心头肉,像我,学以致用,否则学了有何用。若是懂的写程序,该想想放到哪里去用
头像
mikeandmore
帖子: 109
注册时间: 2005-10-13 18:29

#6

帖子 mikeandmore » 2007-12-16 9:44

MFC和WxWidget是很geek的。。。
利用一堆很BTBTBTBT的Macro实现event。。。是不合OOP的
以至于现在wx想要重写event处理,想gtkmm和WTL一样利用template实现,基本原理,见这个月和下个月的《程序员》,侯捷先生的文章。。。

这也是MS放弃MFC的原因。。。
所谓cross compile就是在host下编译其它OS的binary。。。主要是用于嵌入式,和python无关。。。

现在Desktop还是迷茫。。。
MFC隐退了,.NET太慢,Java不理Desktop。。。。可能Qt是个很好的选择吧。。。
至少这几年的Desktop很多都是Qt的Google Earth, Opera。。。。
Gtk/Gtkmm系列也是很有竞争力,但是文档到今年8月才完善。。。。
skycn
帖子: 30
注册时间: 2006-06-05 23:27

#7

帖子 skycn » 2007-12-16 21:30

我看了一下mingw
但。。。。
我觉得mingw只能算是个user mode windows in linux吧
真正做到点平台无关的算是java吧,但java也不好,最讨厌的是layout,其次是jvm
其实除了现在的高级语言如c#及java,或python外,代码都是很恶心的,甚至是java这样完全(所谓的)oop的语言也有很多很恶心的代码
个人觉得MACRO不是什么坏事,我反倒觉得挺好看的

其实wxwidget以前就叫wxwindow的,听说后来是因为ms才改了名字
QT好么? 你喜欢KDE么? 我觉得gnome比KDE要好很多,不过QT及WXWIDGET的机制是比MFC改进了许多,但毕竟MFC是个划高超的作品,算是块基石了
showboy
帖子: 122
注册时间: 2006-11-26 14:41

#8

帖子 showboy » 2007-12-18 15:21

mikeandmore 写了:没啥技术含量和意义。。。
首先。VC6是淘汰产品。。。不合你自己的逻辑
其次,我还以为是mingw作cross compile要是那样的话就有点技术含量了。。。因为嵌入式设备大多是cross compile的,所以意义还是比较大。
最后,市场决定产品,但是现在Linux Desktop才是市场的新区域,你是愿意随波逐流,去更危险的竞争还是动动脑筋另辟蹊径,是你个人的竞争风格了。。。
嵌入式的都是交叉编译,这个人人都知道,哪是CPU体系的问题,但是vc6还不是x86,
这个怎么能说成cross compile
Baytars
帖子: 1
注册时间: 2020-03-13 10:19
系统: Manjaro Linux

Re: [原创]在linux系统中编写windows程序并连接成二进制文件

#9

帖子 Baytars » 2020-03-13 10:27

代码: 全选

"Basemake"="C:\\Program Files\\Microsoft Platform SDK\\Include\\BKOffice.Mak\\"
"Bkoffice"="C:\\Program Files\\Microsoft Platform SDK\\"
这两行是什么意思?在 PSDK 被 Windows SDK 取代的今天还有用吗?
回复