6


0

#defineディレクティブにバージョン番号付きのヘッダファイルを含むCプロジェクト(VS2005)があります。 今私は、ツインC#プロジェクトにまったく同じ番号を含める必要があります。 最善の方法は何ですか?

私はこのファイルをリソースとして含めることを考えています。そして実行時に正規表現を使って解析してバージョン番号を回復しますが、もっと良い方法があると思いますか。

バージョンを.hファイルの外に移動することはできません。ビルドシステムもそれに依存し、C#プロジェクトは適合させる必要があります。

7 Answer


5


私は、.hファイルを処理してそれを .cs file. Its very easy and the source files will then be part of your C#ソリューション(.hファイルが変更されると更新されます)をクリックすると、エディタなどで開くことができます。

#defineが1つしかない場合は、少しやり過ぎるかもしれませんが、それらがいっぱいのファイル(たとえば、mfc resource.hファイルなど)があると、この解決策は大きな勝利になります。

例:DefineConverter.ttというファイルを作成してプロジェクトに追加し、マークされた行を.hファイルを参照するように変更すると、プロジェクト内に静的なconstエントリでいっぱいの新しいクラスが作成されます。 (入力ファイルはプロジェクトファイルからの相対パスです。絶対パスが必要な場合はhostspecific = falseを設定してください)。

<#@ template language = "C#v3.5" hostspecific = "True" debug = "True"#> <#@ output extension = "cs"#> <#@アセンブリ名= "System.Core.dll"# > <#@ import namespace = "System"#> <#@ import namespace = "System.Collections.Generic"#> <#@ import namespace = "System.IO"#>

<#string input_file = this.Host.ResolvePath( "resource.h"); <----このStreamReaderが定義する変更= new StreamReader(input_file); #>
//------------------------------------------------------------------------------
//     This code was generated by template for T4
//     Generated at <#=DateTime.Now#>
//------------------------------------------------------------------------------

名前空間定数{publicクラス<#= System.IO.Path.GetFileNameWithoutExtension(input_file)#> {<#//定数の定義

while(define.Peek()> = 0){文字列def = definitions.ReadLine(); string [] parts; if(def.Length> 3)


3


MSDNは私達に言います:

_ 通常、CおよびC ++で行われているように、#defineディレクティブを使用して定数値を宣言することはできません。 C#の定数は、クラスまたは構造体の静的メンバーとして定義するのが最善です。 そのような定数がいくつかある場合は、それらを保持するために別の "Constants"クラスを作成することを検討してください。 _

あなたはあなたの定数の周りにクラスラッパーを含むマネージドCを使ってライブラリを作成することができます。 その後、C#プロジェクトからこのクラスを参照できます。 定数宣言に* const <type> の代わりに readonly <type> *を使用することを忘れないでください。


2


csファイルでCプリプロセッサを実行するにはプリビルドイベントを使用し、プリビルドステップを元に戻すにはポストビルドイベントを使用できます。 プリプロセッサは単なるテキスト置換システムなので、これは可能です。
// version header file
#defineバージョン "1.01"

// C# code
#include "version.h"
// somewhere in a class
文字列version = Version。

そしてプリプロセッサは以下を生成します。

// C# code
// somewhere in a class
文字列version = "1.01";


2


あなたはほんの数ステップであなたが望むものを達成することができます:

  1. MSBuildタスクを作成する - http://msdn.microsoft.com/en-us/library/t9883dzc.aspx

  2. プロジェクトファイルを更新して、ビルド前に作成されたタスクへの呼び出しを含めます

タスクは、参照したヘッダー.hファイルの場所を持つパラメーターを受け取ります。 次にバージョンを抽出し、そのバージョンを以前に作成したC#プレースホルダファイルに入れます。 または、それが問題ない場合は、通常バージョンを保持するAssemblyInfo.csを使用することを考えることもできます。

追加情報が必要な場合は、コメントしてください。


1


この.hファイルを含む単純なC / Cユーティリティを作成し、C#で使用できるファイルを動的に作成できます。 このユーティリティは、ビルド前段階としてC#プロジェクトの一部として実行できます。 これにより、常に元のファイルと同期します。


0


私は#define FOO "bar"をC#で使用可能なものに変換するPythonスクリプトを書きました。そして私のC#プロジェクトのビルド前のステップでそれを使用しています。 できます。

#messages.hファイルの#definesをMessagesDotH.csのconstに変換します。

インポート再インポートosインポート統計

def convert_h_to_cs(fin、fout):finの行の場合:m!= Noneの場合:m = re.match(r "^#define(。*)\"(。*)\ ""、line):if m.group ()!=なし:fout.write( "public const string" \
                + m.group(1) \
                + " = \"" \
                + m.group(2) \
                + "\";\n" )
re.match(r "^ //"、line)!=なしの場合:fout.write(line)

fin = open( '.. \ common_cpp \ messages.h')fout = open( '.. \ user_setup \ MessagesDotH.cs.tmp'、 'w')

fout.write( 'using System; \ n')fout.write( 'ネームスペースxrisk {class MessagesDotH {\ n')

convert_h_to_cs(fin、fout)

fout.write( '}}')

fout.close()

s1 = open( '.. \ user_setup \ MessagesDotH.cs.tmp')。read()

s2 = open( '.. \ user_setup \ MessagesDotH.cs')。read()

s1!= s2の場合:os.chmod( '.. \ user_setup \ MessagesDotH.cs'、stat.S_IWRITE)print '古いMessagesDotH.csを削除します。os.remove(' .. \ user_setup \ MessagesDotH.cs ')print' tmpをMessagesDotH.csのos.rename( '.. \ user_setup \ MessagesDotH.cs.tmp'、 '.. \ user_setup \ MessagesDotH.cs')に変更します。 同じMessagesDotH.csを使用する


0


gbjbaanbのソリューションを基に、特定のディレクトリ内のすべての.hファイルを見つけ出し、それらを複数のクラスを持つ.csファイルにロールする.ttファイルを作成しました。

違い

  • ダブルスのサポートを追加しました

  • try-catchからTryParseに切り替えました

  • 複数の.hファイルを読み込む

  • 'const’の代わりに 'readonly’を使用します

  • *で終わる#define行をトリミングします。

  • 名前空間は、プロジェクト内の.ttの場所に基づいて設定されます。

'' '' '

<#@ template language = "C#" hostspecific = "True" debug = "True"#> <#@ output extension = "cs"#> <#@アセンブリ名= "System.Core.dll"#> <#@ import namespace = "System"#> <#@ import namespace = "System.Collections.Generic"#> <#@ import namespace = "System.IO"#> <#string hPath = Host.ResolveAssemblyReference( "$(ProjectDir) ")" ProgramData \\ DeltaTau \\ "; string [] hFiles = System.IO.Directory.GetFiles(hPath、 "* .h"、System.IO.SearchOption.AllDirectories); var namespaceName = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData( "NamespaceHint"); #>
//------------------------------------------------------------------------------
//     This code was generated by template for T4
//     Generated at <#=DateTime.Now#>
//------------------------------------------------------------------------------

namespace <#= namespaceName#> {<#foreach(hFilesの文字列input_file){StreamReaderの定義= new StreamReader(input_file); #>パブリッククラス<#= System.IO.Path.GetFileNameWithoutExtension(input_file)#> {<#//定数の定義

while(define.Peek()> = 0){文字列def = definitions.ReadLine(); string [] parts; if(def.Length> 3)