青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-341  評(píng)論-2670  文章-0  trackbacks-0
    在制作GacUI讀pdb生成代碼的過程中,感受到了C++語言設(shè)計(jì)和dll的需求之間的鴻溝。對(duì)于一個(gè)充分利用了C++各種功能的類庫來說,制作成dll具有非常大的困難,特別是在函數(shù)返回POD(Plain Old Data)的引用,和輸入輸出帶有泛型的類上面。所以現(xiàn)在還是決定以源代碼的方式來發(fā)布GacUI。但是pdb生成代碼并沒有白做,因?yàn)榉瓷溥€是存在的。但是因?yàn)镚acUI一共有48000行代碼,80多個(gè)源代碼文件,直接發(fā)布使用起來總是不方便。所以我寫了個(gè)小工具,根據(jù)xml的配置來將源代碼合并成少數(shù)幾個(gè)比較大的代碼文件。這樣使用的時(shí)候,只需要直接把幾個(gè)cpp拖進(jìn)工程里面,就可以使用了。而且根據(jù)之前發(fā)布的一個(gè)投票,似乎大家也最喜歡這種方法。因此這次的決定,僅僅刪掉了作為backup plan的dll方法。

    這里我給出小工具的代碼和配置文件。這個(gè)配置文件是基于GacUI做出來的,不過大家可以修改它,以便用于自己的工程上面:
<?xml version="1.0" encoding="utf-8" ?>
<codegen>
  
<projects>
    
<project path="..\..\..\GacUISrc\GacUISrc.vcxproj" />
  
</projects>
  
<categories>
    
<category name="vlpp" pattern="\Library\"/>
    
<category name="gacui" pattern="\GacUILibrary\">
      
<except filename="GacUI_WinMain.cpp" />
      
<except filename="GuiTypeDescriptorImpHelper.cpp" />
      
<except filename="GuiTypeDescriptorImpProvider_codegen.cpp" />
    
</category>
  
</categories>
  
<output path="..\..\..\GacUILibraryExternal\">
    
<codepair category="vlpp" filename="Vlpp" />
    
<codepair category="gacui" filename="GacUI" />
    
<header source="..\..\..\GacUILibrary\GacUI.h" filename="GacUIIncludes" />
  
</output>
</codegen>

    在這里面,project包含了用于開發(fā)這個(gè)工程的所有VC++2010的工程文件的地址,然后使用category對(duì)他們進(jìn)行分類(pattern是文件全名的某個(gè)部分),最后對(duì)每一個(gè)部分生成一對(duì)cpp和h。在最后生成代碼對(duì)的時(shí)候,如果源代碼從一開始就存在依賴關(guān)系的話,那么在代碼對(duì)的h文件里面,會(huì)包含依賴的代碼對(duì)的h。在這里,vlpp是獨(dú)立的,而gacui依賴了vlpp,所以gacui.h將會(huì)#include"vlpp.h",而cpp只include自己的h文件。output里面除了codepair以外還有header,header是不參與codepair計(jì)算的,純粹為了生成“可以省事直接include”的頭文件。在這個(gè)例子里面,GacUIIncludes.h將會(huì)包含完整的GacUI.h和一部分的Vlpp.h,而且是可以通過編譯的。

 驅(qū)動(dòng)器 E 中的卷沒有標(biāo)簽。
 卷的序列號(hào)是 
9614-79B9

 E:\Codeplex\vlpp\Workspace\Tools\Release\SideProjects\GacUISrc\GacUILibraryExternal 的目錄

2012/02/29  21:42    <DIR>          .
2012/02/29  21:42    <DIR>          ..
2012/02/29  21:42                 0 dir.txt
2012/02/29  21:18           677,987 GacUI.cpp
2012/02/29  21:18           304,231 GacUI.h
2012/02/29  21:18           481,551 GacUIIncludes.h
2012/02/29  21:18            69,348 Vlpp.cpp
2012/02/29  21:18           310,126 Vlpp.h
               
6 個(gè)文件      1,843,243 字節(jié)
               
2 個(gè)目錄 166,357,680,128 可用字節(jié)

   在生成的時(shí)候,生成器將會(huì)閱讀代碼本身,然后獲取#include "path",然后對(duì)他們的關(guān)系進(jìn)行處理。這個(gè)工具的代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Linq;
using System.Text.RegularExpressions;

namespace Codegen
{
    
class Program
    {
        
static string[] GetCppFiles(string projectFile)
        {
            
string np = @"http://schemas.microsoft.com/developer/msbuild/2003";
            XDocument document 
= XDocument.Load(projectFile);
            
return document
                .Root
                .Elements(XName.Get(
"ItemGroup", np))
                .SelectMany(e 
=> e.Elements(XName.Get("ClCompile", np)))
                .Select(e 
=> Path.GetFullPath(Path.GetDirectoryName(projectFile) + "\\" + e.Attribute("Include").Value))
                .ToArray();
        }

        
static Dictionary<stringstring[]> CategorizeCodeFiles(XDocument config, string[] files)
        {
            Dictionary
<stringstring[]> categorizedFiles = new Dictionary<stringstring[]>();
            
foreach (var e in config.Root.Element("categories").Elements("category"))
            {
                
string name = e.Attribute("name").Value;
                
string pattern = e.Attribute("pattern").Value.ToUpper();
                
string[] exceptions = e.Elements("except").Select(x => x.Attribute("filename").Value.ToUpper()).ToArray();
                categorizedFiles.Add(
                    name,
                    files
                        .Where(f 
=> f.ToUpper().Contains(pattern))
                        .Where(f 
=> !exceptions.Contains(Path.GetFileName(f).ToUpper()))
                        .ToArray()
                        );
            }
            
foreach (var a in categorizedFiles.Keys)
            {
                
foreach (var b in categorizedFiles.Keys)
                {
                    
if (a != b)
                    {
                        
if (categorizedFiles[a].Intersect(categorizedFiles[b]).Count() != 0)
                        {
                            
throw new ArgumentException();
                        }
                    }
                }
            }
            
return categorizedFiles;
        }

        
static Dictionary<stringstring[]> ScannedFiles = new Dictionary<stringstring[]>();
        
static Regex IncludeRegex = new Regex(@"^\s*\#include\s*""(?<path>[^""]+)""\s*$");
        
static Regex IncludeSystemRegex = new Regex(@"^\s*\#include\s*\<(?<path>[^""]+)\>\s*$");

        
static string[] GetIncludedFiles(string codeFile)
        {
            codeFile 
= Path.GetFullPath(codeFile).ToUpper();
            
string[] result = null;
            
if (!ScannedFiles.TryGetValue(codeFile, out result))
            {
                List
<string> directIncludeFiles = new List<string>();
                
foreach (var line in File.ReadAllLines(codeFile))
                {
                    Match match 
= IncludeRegex.Match(line);
                    
if (match.Success)
                    {
                        
string path = match.Groups["path"].Value;
                        path 
= Path.GetFullPath(Path.GetDirectoryName(codeFile) + @"\" + path).ToUpper();
                        
if (!directIncludeFiles.Contains(path))
                        {
                            directIncludeFiles.Add(path);
                        }
                    }
                }

                
for (int i = directIncludeFiles.Count - 1; i >= 0; i--)
                {
                    directIncludeFiles.InsertRange(i, GetIncludedFiles(directIncludeFiles[i]));
                }
                result 
= directIncludeFiles.Distinct().ToArray();
                ScannedFiles.Add(codeFile, result);
            }
            
return result;
        }

        
static string[] SortDependecies(Dictionary<stringstring[]> dependeicies)
        {
            var dep 
= dependeicies.ToDictionary(p => p.Key, p => new HashSet<string>(p.Value));
            List
<string> sorted = new List<string>();
            
while (dep.Count > 0)
            {
                
bool found = false;
                
foreach (var p in dep)
                {
                    
if (p.Value.Count == 0)
                    {
                        found 
= true;
                        sorted.Add(p.Key);
                        
foreach (var q in dep.Values)
                        {
                            q.Remove(p.Key);
                        }
                        dep.Remove(p.Key);
                        
break;
                    }
                }
                
if (!found)
                {
                    
throw new ArgumentException();
                }
            }
            
return sorted.ToArray();
        }

        
static void Combine(string[] files, string outputFilename, HashSet<string> systemIncludes, params string[] externalIncludes)
        {
            
try
            {
                
using (StreamWriter writer = new StreamWriter(new FileStream(outputFilename, FileMode.Create), Encoding.Default))
                {
                    writer.WriteLine(
"/***********************************************************************");
                    writer.WriteLine(
"THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY");
                    writer.WriteLine(
"DEVELOPER: 陳梓瀚(vczh)");
                    writer.WriteLine(
"***********************************************************************/");
                    
foreach (var inc in externalIncludes)
                    {
                        writer.WriteLine(
"#include \"{0}\"", inc);
                    }

                    
foreach (var file in files)
                    {
                        writer.WriteLine(
"");
                        writer.WriteLine(
"/***********************************************************************");
                        writer.WriteLine(file);
                        writer.WriteLine(
"***********************************************************************/");
                        
foreach (var line in File.ReadAllLines(file, Encoding.Default))
                        {
                            Match match 
= null;

                            match 
= IncludeSystemRegex.Match(line);
                            
if (match.Success)
                            {
                                
if (systemIncludes.Add(match.Groups["path"].Value.ToUpper()))
                                {
                                    writer.WriteLine(line);
                                }
                            }
                            
else
                            {
                                match 
= IncludeRegex.Match(line);
                                
if (!match.Success)
                                {
                                    writer.WriteLine(line);
                                }
                            }
                        }
                    }
                }
                Console.WriteLine(
"Succeeded to write: {0}", outputFilename);
            }
            
catch (Exception)
            {
                Console.WriteLine(
"Failed to write: {0}", outputFilename);
            }
        }

        
static void Combine(string inputFilename, string outputFilename, params string[] externalIncludes)
        {
            HashSet
<string> systemIncludes = new HashSet<string>();
            
string[] files = GetIncludedFiles(inputFilename).Concat(new string[] { inputFilename }).Distinct().ToArray();
            Combine(files, outputFilename, systemIncludes, externalIncludes);
        }

        
static void Main(string[] args)
        {
            
// load configuration
            XDocument config = XDocument.Load("CodegenConfig.xml");
            
string folder = Path.GetDirectoryName(typeof(Program).Assembly.Location) + "\\";

            
// collect project files
            string[] projectFiles = config.Root
                .Element(
"projects")
                .Elements(
"project")
                .Select(e 
=> Path.GetFullPath(folder + e.Attribute("path").Value))
                .ToArray();

            
// collect code files
            string[] unprocessedCppFiles = projectFiles.SelectMany(GetCppFiles).Distinct().ToArray();
            
string[] unprocessedHeaderFiles = unprocessedCppFiles.SelectMany(GetIncludedFiles).Distinct().ToArray();

            
// categorize code files
            var categorizedCppFiles = CategorizeCodeFiles(config, unprocessedCppFiles);
            var categorizedHeaderFiles 
= CategorizeCodeFiles(config, unprocessedHeaderFiles);
            var outputFolder 
= Path.GetFullPath(folder + config.Root.Element("output").Attribute("path").Value);
            var categorizedOutput 
= config.Root
                .Element(
"output")
                .Elements(
"codepair")
                .ToDictionary(
                    e 
=> e.Attribute("category").Value,
                    e 
=> Path.GetFullPath(outputFolder + e.Attribute("filename").Value
                    ));

            
// calculate category dependencies
            var categoryDependencies = categorizedCppFiles
                .Keys
                .Select(k 
=>
                    {
                        var headerFiles 
= categorizedCppFiles[k]
                            .SelectMany(GetIncludedFiles)
                            .Distinct()
                            .ToArray();
                        var keys 
= categorizedHeaderFiles
                            .Where(p 
=> p.Value.Any(h => headerFiles.Contains(h)))
                            .Select(p 
=> p.Key)
                            .Except(
new string[] { k })
                            .ToArray();
                        
return Tuple.Create(k, keys);
                    })
                .ToDictionary(t 
=> t.Item1, t => t.Item2);

            
// sort categories by dependencies
            var categoryOrder = SortDependecies(categoryDependencies);
            Dictionary
<string, HashSet<string>> categorizedSystemIncludes = new Dictionary<string, HashSet<string>>();

            
// generate code pair header files
            foreach (var c in categoryOrder)
            {
                
string output = categorizedOutput[c] + ".h";
                List
<string> includes = new List<string>();
                
foreach (var dep in categoryDependencies[c])
                {
                    includes.AddRange(categorizedSystemIncludes[dep]);
                }
                HashSet
<string> systemIncludes = new HashSet<string>(includes.Distinct());
                categorizedSystemIncludes.Add(c, systemIncludes);
                Combine(
                    categorizedHeaderFiles[c],
                    output,
                    systemIncludes,
                    categoryDependencies[c]
                        .Select(d 
=> Path.GetFileName(categorizedOutput[d] + ".h"))
                        .ToArray()
                    );
            }

            
// generate code pair cpp files
            foreach (var c in categoryOrder)
            {
                
string output = categorizedOutput[c];
                
string outputHeader = Path.GetFileName(output + ".h");
                
string outputCpp = output + ".cpp";
                HashSet
<string> systemIncludes = categorizedSystemIncludes[c];
                Combine(
                    categorizedCppFiles[c],
                    outputCpp,
                    systemIncludes,
                    outputHeader
                    );
            }

            
// generate header files
            var headerOutput = config.Root
                .Element(
"output")
                .Elements(
"header")
                .ToDictionary(
                    e 
=> Path.GetFullPath(folder + e.Attribute("source").Value),
                    e 
=> Path.GetFullPath(outputFolder + e.Attribute("filename").Value)
                    );
            
foreach (var o in headerOutput)
            {
                Combine(o.Key, o.Value 
+ ".h");
            }
        }
    }
}

    代碼已經(jīng)checkin在了Vczh Library++3.0(Tools\Release\SideProjects\GacUISrc\GacUISrc.sln)下面,里面也包含了生成后的代碼。
posted on 2012-02-29 05:34 陳梓瀚(vczh) 閱讀(4038) 評(píng)論(9)  編輯 收藏 引用 所屬分類: GacUI

評(píng)論:
# re: 最終還是決定直接以源代碼方式發(fā)布GacUI了 2012-02-29 07:32 | Exoticknight
只看到開源二字就應(yīng)該支持,雖然我暫時(shí)不懂C++  回復(fù)  更多評(píng)論
  
# re: 最終還是決定直接以源代碼方式發(fā)布GacUI了 2012-02-29 09:17 | Zblc
強(qiáng)烈支持 拭目以待 = =+   回復(fù)  更多評(píng)論
  
# re: 最終還是決定直接以源代碼方式發(fā)布GacUI了 2012-02-29 18:29 | 春秋十一月
本想幫你的腳本弄個(gè)benchmark, 和lua之類的對(duì)比一下速度。無奈那么多數(shù)學(xué)函數(shù)里,就木有找到sqrt函數(shù),太杯具了。可以軟實(shí)現(xiàn)sqrt,但結(jié)果肯定不公平,無奈只得放棄。  回復(fù)  更多評(píng)論
  
# re: 最終還是決定直接以源代碼方式發(fā)布GacUI了[未登錄] 2012-02-29 21:15 | 陳梓瀚(vczh)
@春秋十一月
一定要sqrt?  回復(fù)  更多評(píng)論
  
# re: 最終還是決定直接以源代碼方式發(fā)布GacUI了 2012-02-29 22:58 | phoenixbing
不容易,真不容易。48000行代碼,80多個(gè)源代碼文件  回復(fù)  更多評(píng)論
  
# re: 最終還是決定直接以源代碼方式發(fā)布GacUI了 2012-02-29 22:58 | phoenixbing
不能支持你更多  回復(fù)  更多評(píng)論
  
# re: 最終還是決定直接以源代碼方式發(fā)布GacUI了 2012-03-01 04:42 | bennycen
火速前來參拜Orz  回復(fù)  更多評(píng)論
  
# re: 最終還是決定直接以源代碼方式發(fā)布GacUI了[未登錄] 2012-03-01 09:40 | 潘孫友
還是以源碼方式提供吧,最直接最給力了!  回復(fù)  更多評(píng)論
  
# re: 最終還是決定直接以源代碼方式發(fā)布GacUI了 2012-03-01 17:34 | 空明流轉(zhuǎn)
@春秋十一月
SQRT其實(shí)沒啥比較的價(jià)值,因?yàn)檫@個(gè)不是什么常用的函數(shù),如果以數(shù)學(xué)為主導(dǎo)的腳本,那肯定有匯編實(shí)現(xiàn),如果是以邏輯為主導(dǎo)的,那一般都是轉(zhuǎn)發(fā)CRT的SQRT了。  回復(fù)  更多評(píng)論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国内精品福利| 欧美.www| 乱中年女人伦av一区二区| 亚洲综合第一| 欧美亚洲视频一区二区| 欧美一区二区三区在线| 欧美在线看片a免费观看| 久久久久久久一区二区| 美国成人毛片| 欧美激情精品久久久久久黑人| 欧美激情视频在线免费观看 欧美视频免费一| 蜜臀久久99精品久久久画质超高清| 欧美成人官网二区| 亚洲精品综合| 亚洲综合精品| 欧美成人免费在线观看| 欧美日韩成人在线播放| 国产欧美亚洲一区| 91久久国产综合久久| 亚洲香蕉伊综合在人在线视看| 亚洲欧美日韩中文视频| 免费观看欧美在线视频的网站| 亚洲精品美女在线观看| 亚洲视频日本| 久久一区中文字幕| 欧美日韩系列| 亚洲第一在线综合在线| 亚洲一区二区三区在线看| 免费观看久久久4p| 亚洲欧洲在线免费| 亚洲自拍电影| 免费观看久久久4p| 国产精品视频九色porn| 一区二区三区在线免费观看| 99re66热这里只有精品4| 久久精品一区中文字幕| 亚洲精品资源| 欧美99久久| 国外视频精品毛片| 亚洲影院高清在线| 亚洲欧洲久久| 麻豆精品视频在线| 国产人妖伪娘一区91| 在线亚洲伦理| 欧美激情视频在线播放 | 久久偷窥视频| 国产欧美一区二区精品忘忧草| 一区二区高清视频| 亚洲黄色在线看| 欧美成人免费网| 亚洲欧洲精品一区二区三区波多野1战4 | 欧美在线免费视频| 在线视频一区二区| 欧美日韩精品在线观看| 最新国产拍偷乱拍精品| 欧美91视频| 久久综合福利| 在线成人性视频| 欧美不卡高清| 久久夜色精品国产欧美乱极品| 国产一区清纯| 久久免费观看视频| 欧美专区亚洲专区| 国内精品久久久| 老鸭窝91久久精品色噜噜导演| 久久精品噜噜噜成人av农村| 好吊一区二区三区| 久久视频在线视频| 免费看的黄色欧美网站| 最新69国产成人精品视频免费| 嫩草影视亚洲| 欧美精品在线播放| 亚洲欧美日韩国产一区二区三区| 一区二区三区福利| 国产精品爽黄69| 久久久五月婷婷| 另类天堂视频在线观看| 亚洲欧洲日本mm| 亚洲午夜精品视频| 亚洲综合二区| 亚洲电影免费| 艳妇臀荡乳欲伦亚洲一区| 日韩视频在线观看国产| 亚久久调教视频| 午夜天堂精品久久久久| 在线观看的日韩av| 亚洲国产欧美久久| 国产精品美女久久| 亚洲高清久久| 一区二区三区av| 影音先锋久久| av成人手机在线| 激情综合在线| 亚洲免费av片| 国内一区二区在线视频观看| 欧美国内亚洲| 国产精品露脸自拍| 久久综合中文色婷婷| 欧美日韩在线观看一区二区三区| 久久久久国产精品厨房| 欧美人成在线| 久久深夜福利| 国产精品黄视频| 欧美韩日亚洲| 国产精品你懂的| 最新亚洲视频| 在线播放亚洲一区| 亚洲女ⅴideoshd黑人| 日韩视频永久免费| 欧美一区二区三区免费观看| 99精品热视频| 久久看片网站| 久久国产精品久久久久久久久久| 欧美bbbxxxxx| 久久亚洲一区| 国产精品视频内| 一区二区精品在线| 一区二区亚洲精品| 亚洲欧美在线另类| 亚洲视频免费| 欧美bbbxxxxx| 看欧美日韩国产| 国产亚洲午夜高清国产拍精品| 亚洲肉体裸体xxxx137| 亚洲国产一区二区三区青草影视| 欧美在线观看日本一区| 亚洲伊人观看| 欧美午夜宅男影院在线观看| 91久久精品国产91性色tv| 精品成人一区| 欧美伊人久久| 久久精品视频va| 国产区精品视频| 亚洲欧美国产高清| 亚洲免费在线观看| 国产精品成人一区二区三区吃奶| 亚洲激情电影中文字幕| 日韩一级精品| 欧美日韩一区不卡| 亚洲图片你懂的| 午夜精品久久久久久久久久久| 欧美视频在线不卡| 亚洲性人人天天夜夜摸| 欧美一区二区精美| 黄色亚洲网站| 麻豆av福利av久久av| 欧美激情在线播放| 一区二区日韩免费看| 欧美呦呦网站| 欧美日韩视频专区在线播放| 亚洲第一天堂无码专区| 亚洲精品中文字幕在线| 欧美日韩国产天堂| 中文精品在线| 老鸭窝毛片一区二区三区| 永久免费精品影视网站| 久久综合伊人77777尤物| 欧美风情在线观看| 夜夜嗨av一区二区三区四季av| 欧美日韩1080p| 亚洲在线免费| 嫩模写真一区二区三区三州| av成人激情| 国产日韩精品一区二区| 久久午夜av| 亚洲手机成人高清视频| 久久久久亚洲综合| 亚洲乱码国产乱码精品精98午夜| 欧美日本高清一区| 欧美伊人久久久久久午夜久久久久| 欧美freesex交免费视频| 亚洲性线免费观看视频成熟| 国产一区二区在线观看免费播放| 久热精品视频在线免费观看| 夜夜嗨av一区二区三区四区 | 麻豆免费精品视频| 宅男噜噜噜66一区二区| 黄色亚洲精品| 欧美视频1区| 麻豆精品一区二区综合av| 一区二区欧美激情| 欧美国产视频日韩| 午夜在线成人av| 日韩午夜三级在线| 激情自拍一区| 国产欧美不卡| 欧美精品麻豆| 久久天天躁狠狠躁夜夜爽蜜月| 一本一本久久| 欧美激情区在线播放| 久久久久高清| 午夜亚洲福利在线老司机| 亚洲精品国产精品国产自| 国产午夜精品一区二区三区欧美| 欧美女同视频| 免费成人美女女| 久久精品视频在线看| 亚洲一卡二卡三卡四卡五卡| 亚洲人成免费| 亚洲国产成人一区|