2012-04-11 64 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不起作用,你可以试试这个。

相关问题