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++ 中将函数声明为使用 char 而不是 wchar_t,并使用“hello all”而不是 L“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 的第二个字节为零,解释为字符串结尾

char*您可以使用该dumpbin /exports yourdll.dll命令验证您编译的 dll 是否将其作为参数导出。

您应该尝试找到 ilasm 的编译器开关,告诉它将其字符串视为宽字符。

于 2010-10-13T19:18:22.260 回答
0

我最终接受了 Sandeep 的建议并构建了一个 C++ 混合模式 DLL。

于 2010-10-13T23:11:06.773 回答