我正在尝试从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
感谢任何帮助!
答案 0 :(得分:2)
这正是函数期望char []但接收到wchar_t []的症状:第一个wchar_t的第二个字节为零,被解释为字符串结尾
您可以使用char*
命令验证已编译的dll是否将其函数作为dumpbin /exports yourdll.dll
参数导出。
您应该尝试找到ilasm的编译器开关,告诉它将字符串视为宽字符。
答案 1 :(得分:0)
我最终选择了Sandeep的建议并构建了一个C ++混合模式DLL。