包装器作为EXE工作,但不作为DLL(用C ++ / CLI编写,包装C#类)

时间:2015-12-09 03:44:30

标签: c# .net visual-c++ c++-cli dllexport

我想在C#中编写一个必须提供某些功能(API)的DLL。我对MSIL代码修饰符感到失望,它们承诺提供C#方法作为DLL导出。所以我现在正试图让一个桥接DLL工作,用C ++ / CLI编写,应该调用静态C#方法。 C ++ / CLI对我来说是新的和神秘的。

这些是我在命令行中使用的命令:

  • 将C#文件编译为DLL文件:csc /target:library CSharpClass.cs
  • 将C ++ / CLI包装器文件编译为可执行文件:cl /clr Test.cpp /link user32.lib
  • 将C ++ / CLI包装器文件编译为DLL文件:cl /clr /LD Test.cpp /link user32.lib
  • 运行DLL文件的导出功能:winapiexec Test.dll@CppTestFunction

在C ++ / CLI文件的评论中,我描述了正在发生的事情。

C#文件:

using System;
using System.Runtime.InteropServices;

namespace CSharpNamespace {
    public static class CSharpClass {
        [DllImport("user32.dll")]
        private static extern int MessageBox(IntPtr hWnd, string text,
                string caption, int options);

        public static void TestMethod() {
            MessageBox(IntPtr.Zero, "Test", "", 0);
        }
    }
}

C ++ / CLI文件:

#using <mscorlib.dll>

// It doesn't matter, whether this path is absolute or not:
#using "CSharpClass.dll"

#include <windows.h>

using namespace CSharpNamespace;

extern "C" __declspec(dllexport) void CppTestFunction() {
    CSharpClass::TestMethod();  // Works with EXE; DLL crashes
//    System::Console::Beep();  // Works with EXE and DLL
//    MessageBoxW(NULL, (LPCWSTR)"", (LPCWSTR)"", 0);  // Works with EXE and DLL
}

void main() {
    CppTestFunction();
}

知道DLL版本为什么不能成功调用C#代码?

1 个答案:

答案 0 :(得分:1)

Hans Passant的评论是正确的。谢谢你的提示!

工作测试用例

命令行:

  • csc /target:library CSharpClass.cs
  • cl /clr /LD TestDll.cpp /link user32.lib
  • cl DllCallingTestExe.cpp /link TestDll.lib

TestDll.cpp

#using <mscorlib.dll>
#using "CSharpClass.dll"

#include "TestDll.h"

using namespace CSharpNamespace;

extern "C" __declspec(dllexport) void __stdcall CppTestMethod() {
    CSharpClass::TestMethod();
}

TestDll.h

extern "C" __declspec(dllexport) void __stdcall CppTestMethod();

DllCallingTestExe.cpp

#include "TestDll.h"

void main() {
    CppTestMethod();
}