包装器作为 EXE,但不是作为 DLL(用 C++/CLI 编写,环绕 C# class)
Wrapper working as EXE, but not as DLL (written in C++/CLI, wrapping around C# class)
我想用 C# 编写一个必须提供某些功能的 DLL (API)。我对承诺提供 C# 方法作为 DLL 导出的 MSIL 代码修饰符感到失望。所以我现在正试图让桥接 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# 代码吗?
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();
}
我想用 C# 编写一个必须提供某些功能的 DLL (API)。我对承诺提供 C# 方法作为 DLL 导出的 MSIL 代码修饰符感到失望。所以我现在正试图让桥接 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# 代码吗?
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();
}