2012-04-11 48 views
15

我努力學習的P/Invoke,所以我創建了C++無法調用C++ DLL在C#中,當找到一個切入點

KingFucs.h一個簡單的DLL:

namespace KingFuncs 
{ 
    class KingFuncs 
    { 
    public: 
     static __declspec(dllexport) int GiveMeNumber(int i); 
    }; 
} 

KingFuns.cpp :

#include "KingFuncs.h" 
#include <stdexcept> 

using namespace std; 

namespace KingFuncs 
{ 
    int KingFuncs::GiveMeNumber(int i) 
    { 
     return i; 
    } 
} 

所以它編譯,然後我複製這個DLL到我的WPF的debug文件夾中,用代碼:

[DllImport("KingFuncDll.dll", EntryPoint = "GiveMeNumber", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern int GiveMeNumber(
       int i 
      ); 

,把它在按一下按鈕:

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    int num = GiveMeNumber(123); 
} 

但它給了我異常:

無法找到DLL 'KingFuncDll.dll' 名爲 'GiveMeNumber' 的切入點。

真的....我做了什麼錯...它顯然能夠找到DLL,否則會是另一個例外。但我的方法名稱完全一樣....我想不出其他原因。

+1

請在這裏看到我的問題:http://stackoverflow.com/questions/9849541/writing-c-intended-to-be-called-from-c – 2012-04-11 16:01:48

+0

我解決了同樣的問題,並描述在[這篇文章] (https://stackoverflow.com/a/45263176/1817569)。 – Hamid 2017-07-23 08:45:52

回答

31

當你導出你的函數時,你需要使用extern "C",這樣你才能抑制C++的名字變形。而且你也不應該嘗試對一個類的成員進行p/invoke。使用免費的功能,而不是:

extern "C" { 
    __declspec(dllexport) int GiveMeNumber(int i) 
    { 
     return i; 
    } 
} 

在管理方面的DllImport屬性是完全錯誤的。請勿使用僅用於Win32 API的SetLastError。如果沒有文本參數,請不要打擾CharSet。不需要ExactSpelling。而調用約定大概是Cdecl

[DllImport("KingFuncDll.dll", CallingConvention=CallingConvention.Cdecl)] 
public static extern int GiveMeNumber(int i); 
+0

謝謝,它工作。但是不可能調用一個類的函數? (這是我第一次使用extern「C」,我認爲我總是需要用C++在類中定義函數) – 2012-04-11 16:23:36

+0

您不需要在C++中的類中定義函數。老式的C函數很好。 – 2012-04-11 16:31:11

0

問題是你正在C++類中聲明C++「函數」,並告訴P/Invoke使用StdCall。

嘗試在類之外聲明一個C++函數,並像你一樣導出它。那麼你的代碼應該工作。

如果你真的必須在類內部有一個C++函數,請看CallingConvention.ThisCall。但你是負責創建非託管類的實例,並把它作爲你的P的第一個參數/ Invoke調用

0

一個dll文件的入口點名稱的文件.exp給出它在debug文件夾中其他地方找到源文件存在。如果dumpbin不起作用,你可以試試這個。

相關問題