2015-12-09 47 views
1

我想在C#中編寫一個必須提供某些功能(API)的DLL。我對MSIL代碼修飾符感到失望,它承諾提供C#方法作爲DLL導出。所以我現在試圖獲得一個橋接DLL工作,用C++/CLI編寫,應該調用靜態C#方法。 C++/CLI對我來說是新的和神祕的。包裝工作EXE,但不是作爲DLL(用C++/CLI編寫,環繞C#類)

這些是我在命令行上使用的命令:

  • 編譯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[email protected]

在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

這種 「winapiexec」 實用工具,您使用的是有點簡陋,尤其是當它沒有告訴我們哪裏出了問題。它確實需要你公開的功能類似於winapi功能。你的不是。它不是__stdcall,它沒有像BOOL這樣的返回類型,也沒有設置錯誤代碼(SetLastError)。而你的C++/CLI程序集實際上並不是一個DLL,那不可能是好的。只是不要使用它。 –

回答

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(); 
}