3

アンマネージド C++ アプリで使用できるように、C# からいくつかの機能をエクスポートしようとしています。テスト プロジェクトでは、まず、文字列をファイルに書き込む単純な関数を含む C# DLL を作成します。次に、ildasm を使用して、これを中間言語 (.il ファイル) に変換します。.il の関数は次のようになります。


  // =============== CLASS MEMBERS DECLARATION ===================

  .class public auto ansi beforefieldinit MyTest.CSharpExportClass extends 

  [mscorlib]System.Object
  {
  .method public hidebysig static void        modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall)   ExportNameOfFunction2(string test) cil managed
    {
  .vtentry 1 : 1
  .export [1] as ExportNameOfFunction2
      // Code size       25 (0x19)
      .maxstack  2
      .locals init ([0] class [mscorlib]System.IO.TextWriter tw)
      IL_0000:  ldstr      "date.txt"
      IL_0005:  newobj     instance void [mscorlib]System.IO.StreamWriter::.ctor(string)
      IL_000a:  stloc.0
    IL_000b:  ldloc.0
    IL_000c:  ldarg.0
    IL_000d:  callvirt   instance void [mscorlib]System.IO.TextWriter::WriteLine(string)
    IL_0012:  ldloc.0
    IL_0013:  callvirt   instance void [mscorlib]System.IO.TextWriter::Close()
    IL_0018:  ret
  } // end of method CSharpExportClass::ExportNameOfFunction2

.method public hidebysig specialname rtspecialname instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method CSharpExportClass::.ctor

} // end of class MyTest.CSharpExportClass

そこにキーワード「ansi」が表示されます... ilasm.exe を使用してこれを C++ DLL に変換した後、C++ アプリでこの関数を使用するためにロードを試みます。


HMODULE hdll = LoadLibraryW(L"CpCsh.dll");
    if(!hdll)
    {       
        return(-1);
    }

    typedef void (__stdcall *_EXP_NAME_OF_FUNCT)(wchar_t*);
    _EXP_NAME_OF_FUNCT      ExportNameOfFunction;

    ExportNameOfFunction = (_EXP_NAME_OF_FUNCT)GetProcAddress(hdll, "ExportNameOfFunction2");

    if(ExportNameOfFunction == NULL)
    {
        return(-1);
    }

    ExportNameOfFunction(L"hello all");

ただし、これは最初の文字 ("h") のみをファイルに書き込みます。C++ で wchar_t の代わりに char を使用する関数を宣言し、L"hello all" の代わりに "hello all" を使用すると、文字列全体がファイルに書き込まれます。

さらにいくつかのメモ: ildasm オプション: /nologo /quiet /out:MyTest.dll MyTest.il /unicode /DLL /resource=MyTest.res /optimize

ilasm オプション: /nologo /out:C:\temp\CpCsh.dll "MyTest.il" /DLL

どんな助けでも大歓迎です!

4

2 に答える 2

2

これはまさに、関数が char[] を期待しているのに wchar_t[] を受け取った場合の症状です。最初の wchar_t の 2 番目のバイトがゼロであり、文字列の終わりとして解釈されます。

char*コマンドを使用して、コンパイルされた dll がその関数を引数としてエクスポートするかどうかを確認できますdumpbin /exports yourdll.dll

文字列をワイド文字として扱うように指示する、ilasm のコンパイラ スイッチを見つけてください。

于 2010-10-13T19:18:22.260 に答える
0

最終的に Sandeep の提案に従い、C++ 混合モード DLL を作成しました。

于 2010-10-13T23:11:06.773 に答える