“无法在 dll 中找到名为 [function] 的入口点”(c++ 到 c# 类型转换)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/653178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 11:57:19  来源:igfitidea点击:

"Unable to find an entry point named [function] in dll" (c++ to c# type conversion)

c#c++dlldllimportextern

提问by Evgeny

I have a dll which comes from a third party, which was written in C++. Here is some information that comes from the dll documentation:

我有一个来自第三方的 dll,它是用 C++ 编写的。以下是来自 dll 文档的一些信息:

//start documentation

RECO_DATA{
wchar_t Surname[200];
wchar_t Firstname[200];
}

Description: Data structure for receiving the function result. All function result will be stored as Unicode (UTF-8).

描述:接收函数结果的数据结构。所有函数结果都将存储为 Unicode (UTF-8)。

Method:

方法:

bool recoCHN_P_Name(char *imgPath,RECO_DATA *o_data);

Input:

输入:

char * imgPath

the full path of the image location for this function to recognize

此函数要识别的图像位置的完整路径

RECO_DATA * o_data

data object for receiving the function result. Function return: True if Success, otherwise false will return.

用于接收函数结果的数据对象。函数返回:如果成功则返回真,否则返回假。

//end documentation

I am trying to call the recoCHN_P_Name from my C# application. To this end, I came up with this code:

我正在尝试从我的 C# 应用程序中调用 recoCHN_P_Name。为此,我想出了这个代码:

The code to import the dll:

导入dll的代码:

    public class cnOCRsdk
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct RECO_DATA{
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=200)]
        public string FirstName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 200)]
        public string Surname;
        }

    [DllImport(@"cnOCRsdk.dll", EntryPoint="recoCHN_P_Name")]
    public static extern bool recoCHN_P_Name(byte[] imgPath, RECO_DATA o_data);
}

The code to call the function:

调用函数的代码:

            cnOCRsdk.RECO_DATA recoData = new cnOCRsdk.RECO_DATA();

        string path = @"C:\WINDOWS\twain_32\twainrgb.bmp";

        System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
        byte[] bytes = encoding.GetBytes(path);

        bool res = cnOCRsdk.recoCHN_P_Name(bytes, recoData);

And the error I'm getting is ""Unable to find an entry point named 'recoCHN_P_Name' in DLL 'cnOCRsdk.dll'." I'm suspecting that I'm having an error in converting a type from C++ to C#. But where exactly ... ?

我得到的错误是“”无法在 DLL 'cnOCRsdk.dll' 中找到名为 'recoCHN_P_Name' 的入口点。”我怀疑我在将类型从 C++ 转换为 C# 时出错。但是究竟在哪里...?

采纳答案by i_am_jorf

First make sure the function is actually exported:

首先确保函数实际导出:

In the Visual Studio Command Prompt, use dumpbin /exports whatever.dll

在 Visual Studio 命令提示符中,使用 dumpbin /exports whatever.dll

回答by paxdiablo

C# doesn't support C++ name mangling and you either need to declare the C++ functions with

C# 不支持 C++ 名称修改,您需要使用以下命令声明 C++ 函数

extern "C" {...}

(may not an option if they're from a third party), or call the mangled name directly if you can get it to work. It may be easier to get the third party to provide a non-mangled interface to the functionality.

(如果它们来自第三方,则可能不是一种选择),或者如果可以使其正常工作,则直接调用损坏的名称。让第三方为该功能提供非损坏的接口可能更容易。

回答by Dan Bystr?m

I'd write a wrapper using C++/CLI. This wrapper will be able to include the .h files and link to the .lib files you got from the third party vendor. Then it is both easy and safe to write a managed interface for your C# program.

我会使用 C++/CLI 编写一个包装器。此包装器将能够包含 .h 文件并链接到您从第三方供应商处获得的 .lib 文件。然后为 C# 程序编写托管接口既简单又安全。

回答by Evgeny

Solved - at least to the point where the program does not break and actually returns me a bool value.

已解决 - 至少到程序不会中断并实际返回一个 bool 值的程度。

The key, I guess, was to specify the entry point as the 'mangled' name

我猜,关键是将入口点指定为 'mangled' 名称

    [DllImport(@"cnOCRsdk.dll", EntryPoint="?recoCHN_P_Name@CcnOCRsdk@@QAE_NPADPAURECO_DATA@@@Z")]
    public static extern bool recoCHN_P_Name(ref string imgPath, ref RECO_DATA o_data);

After that I got some other errors but the 'unable to find entry point' went away.

之后我遇到了其他一些错误,但“无法找到入口点”消失了。

回答by evilfred

You could try using the unmangled name while specifying a CallingConvention in the DllImport

您可以尝试在 DllImport 中指定 CallingConvention 时使用未混淆的名称

回答by uzrgm

Correct EntryPointstring could be found in ".lib" file that comes along with main unmanaged dll.

可以在主非托管 dll 附带的“.lib”文件中找到正确的EntryPoint字符串。

回答by Hamid

I solved the same problem in these steps:

step 1)If you program your custom DLL in C++ using Visual studio,then at the property page of your project set the Common Language Runtime Support (/clr)parameter to Common Language Runtime Support (/clr).

step 2)To function deceleration in .hfile use __declspec(dllexport)keyword like below:

我在这些步骤中解决了同样的问题:

步骤 1)如果您使用 Visual Studio 在 C++ 中编写自定义 DLL,则在项目的属性页将Common Language Runtime Support (/clr)参数设置为Common Language Runtime Support (/clr).

步骤 2)要在.h文件中使用减速功能,请使用__declspec(dllexport)如下关键字:

__declspec(dllexport) double Sum(int a,int b);

step 3)Build and export DLL file, then use the Dependency Walkersoftware to get your function EntryPoint.

step4)Import DLL file In the C# project and set EntryPointand CallingConventionvariable like below:

步骤 3)构建并导出 DLL 文件,然后使用Dependency Walker软件获取您的函数EntryPoint

step4)在 C# 项目中导入 DLL 文件并设置EntryPointCallingConvention变量,如下所示:

[DllImport("custom.dll", EntryPoint = "?Sum@@YAXHHHHHHNNN@Z", CallingConvention = CallingConvention.Cdecl)]

    public static extern double Sum(int a,int b);