在C#中调用C ++ dll时找不到入口点

在C#中调用C ++ dll时找不到入口点

问题描述:

我试图学习P/Invoke,所以我用C ++创建了一个简单的dll

I am trying to learn P/Invoke, so I created a simple dll in C++

KingFucs.h:

KingFucs.h:

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

KingFuns.cpp:

KingFuns.cpp:

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

using namespace std;

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

因此它确实可以编译,然后我将此代码复制到WPF的debug文件夹中,代码为:

So it does compile, then I copied this dll into my WPF's debug folder, with code:

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

并在按钮单击中调用它:

And calling it in button click:

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

但是它给了我一个例外:

But it gives me exception:

在DLL中找不到名为"GiveMeNumber"的入口点 "KingFuncDll.dll".

Unable to find an entry point named 'GiveMeNumber' in DLL 'KingFuncDll.dll'.

真的....我做错了什么...它显然能够找到DLL,否则将是另一个异常.但是我的方法名称是完全相同的...我想不出其他原因了.

Really.... what have I done wrong... It obviously able to find the DLL, otherwise would be another exception. But my method name is exactly the same.... I can't think of other reason.

导出函数时,需要使用extern "C",以便禁止C ++名称修饰.而且,您也不应该尝试与班级成员进行对话.改用免费功能:

You need to use extern "C" when you export your function so that you suppress C++ name mangling. And you also should not try to p/invoke to members of a class. Use free functions instead:

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

在托管方面,您的DllImport属性完全错误.不要使用仅用于Win32 API的SetLastError.如果没有文本参数,请不要设置CharSet.不需要ExactSpelling.调用约定大概是Cdecl.

On the managed side your DllImport attribute is all wrong. Don't use SetLastError which is for Win32 APIs only. Don't bother setting CharSet if there are not text parameters. No need for ExactSpelling. And the calling convention is presumably Cdecl.

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