2016-05-28 6 views
0

アンマネージドアプリケーションの異なるバージョンにロードできる.net-extensionを書きます。 I以下アプリケーションのバージョンに応じてDllImportのコードを動的に生成

some_func_v02some_func_v01を輸入し、some_func_v03機能:

[DllImport("some_library_v1.0.dll", CallingConvention = CallingConvention.Cdecl, 
    CharSet = CharSet.Unicode, EntryPoint = "func_name")] 
extern static private void some_func_v01(string msg); 

[DllImport("some_library_v2.0.dll", CallingConvention = CallingConvention.Cdecl, 
    CharSet = CharSet.Unicode, EntryPoint = "func_name")] 
extern static private void some_func_v02(string msg); 

[DllImport("some_library_v3.0.dll", CallingConvention = CallingConvention.Cdecl, 
    CharSet = CharSet.Unicode, EntryPoint = "func_name")] 
extern static private void some_func_v03(string msg); 

... 

public void some_func(string msg) 
{ 
    switch (Application.Version.Major) 
    { 
    case 1: some_func_v01(msg); break; 
    case 2: some_func_v02(msg); break; 
    case 3: some_func_v03(msg); break; 
    } 
} 

some_libraryライブラリは、ターゲット・アプリケーションの一部であり、アプリケーションのように同じバージョンを持っています。

問題は、新しいバージョンのアプリケーションが表示されるときに私の拡張機能のコードを編集することです。私は動的にアプリケーションのバージョンに応じてコードを生成したいと思います。たとえば、アプリケーションのバージョン1のために:私ができる

[DllImport("some_library_v1.0.dll", CallingConvention = CallingConvention.Cdecl, 
    CharSet = CharSet.Unicode, EntryPoint = "func_name")] 
extern static private void some_func(string msg); 

PowerShellを使用してホスティングを通してそれを行うには、より多くの簡単な方法が存在するかもしれない...私はPowerShellが唯一のこのタスクを実行するために、ホスティング作成したいとは思わないでしょう。

これは簡単な方法ですか?

+0

あなたはhttp://stackoverflow.com/questions/18362368/loading-dlls-at-runtime-in-c-sharpとhttp://stackoverflow.com/questions/6493715/how-現在の製品バージョンを取得するには? – Fruchtzwerg

+0

私のテーマとあなたの指定したテーマとの関係はありません。 –

+1

本当にシンプルです。展開するときにDLLの名前を変更するだけです。 apiが変更されたときに自動化された何かを行うことができ、関数が余分な引数を取得する可能性はゼロです。 –

答えて

1

私は、DLLを動的にロードするのが最善の解決策だと思います。

機能のアドレスを取得するには、WINAPI LoadLibraryGetProcAddressを使用します。次に、Marshal.GetDelegateForFunctionPointerを使用して.netデリゲートを取得します。

例:

//skipping WINAPI native definitions 
//you need to define delegate type: 
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)] 
delegate void MyFuncType(string msg); 


//how to get delegate object: 

var library = LoadLibrary(libraryNameChosenAtRuntime); 
var funcPtr = GetProcAddress(library, funcName); 
var func = Marshal.GetDelegateForFunctionPointer<MyFuncType>(funcPtr); 

// now you can use func as delegate 
// you can store this delegate object somewhere and reuse. 
func("msg"); 
+0

'some_library _ *。dll'はアンマネージドDLLであり、アンマネージホストに既にロードされています。ありがとう、私は今日それを試してみます。 –

0

あなたが外部アプリケーションのバージョンを知っているので、あなたも、したがって、どこか外部アプリケーションのディレクトリ内に存在する外部DLLの場所をそのディレクトリを知っています。あなたが無視したいのは、dllの接尾辞の名前です(この例ではバージョンv_1の部分です)。私は、外部アプリケーションの各バージョンには、そのDLLのバージョンが1つしかないと考えています。

私の仮定が正しければ、あなたはそうのようなこのすべてを達成できます。

  1. バージョン(「some_library」あなたの例では)関係なく、そのファイル名には、常にではありませんDLLのプレフィックスを選択してください
  2. 外部アプリケーションのディレクトリまたはサブディレクトリ(古い.NETを使用している場合はDirectory.EnumerateFilesまたは.GetFiles)のdllの場所にあるすべてのファイルを列挙します。
  3. 接頭辞( "some_library _ *。dll"あなたの例)
  4. 負荷動的にdllを呼び出し、関数を呼び出します(Olehは彼の答えで良い例を与えました)。
+0

'some_library _ *。dll'はアンマネージドDLLであり、アンマネージホストに既にロードされています。 –

関連する問題