1

私がやろうとしているのは、マネージ コードで同じメソッドを使用して、ネイティブ DLL の 2 つのバージョンに対してコンパイルできるようにすることです。

たとえば、これは私のネイティブ メソッド シグネチャになります。

__declspec(dllexport) void MyClass::NativeFoo(const TCHAR* txt)

char*あるビルドで a を受け入れ、別のビルドで aを受け入れるようにコンパイルしますwchar*

pInvoke シグネチャは次のようになります。

[DllImport("Native.dll")]
private static extern void NativeFoo(string txt);

CharSetpInvoke 呼び出しで使用されるを制御できるようにするために、次のメソッドを使用しています。

internal static void SetUnicodeMode(bool state)
{
    MethodInfo m = typeof(ManagedFoo).GetMethod("NativeFoo", BindingFlags.NonPublic | BindingFlags.Static);
    object[] atts = m.GetCustomAttributes(typeof(DllImportAttribute), false);
    DllImportAttribute dllatt = (atts[0] as DllImportAttribute);
    dllatt.CharSet = state ? CharSet.Unicode : CharSet.Ansi;
}

そして、マネージ アセンブリの起動時にこのメソッドを呼び出しています (この時点で、Unicode と mbcs のどちらを使用する必要があるかがわかります)。

このメソッドは例外をスローしませんがCharSet、pInvoke 呼び出しで使用される を変更しません。私は何を間違っていますか?

4

1 に答える 1

2

これは機能しません。CLRは[DllAttribute]の独自のインスタンスを作成し、ユーザーのインスタンスは使用しません。属性コンストラクターの引数に使用される値は、アセンブリメタデータに格納されているため、そのデータを変更することはできません。

先に進むための唯一の合理的な方法は、異なる名前の2つの宣言を使用することです。属性のEntryPointプロパティを使用して、それらを同じエクスポートされた関数にマップします。それ以外の場合、どちらを選択するためにどのトリガーを使用するかは非常に不明確です。もちろん、実際のDLLも異なる必要があります。これは非常に珍しいことです。異なるコンパイラ設定でDLLを再構築する場合、TCHARは異なるタイプの文字になります。特にUNICODEと_UNICODE#defines。前世紀の8ビット文字(TCHAR)をまだ使用する理由は考えられません。健全性チェックはここに強く示されています。

于 2013-03-16T18:16:21.900 に答える