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

Posted

技术标签:

【中文标题】“无法在 dll 中找到名为 [function] 的入口点”(c++ 到 c# 类型转换)【英文标题】:"Unable to find an entry point named [function] in dll" (c++ to c# type conversion) 【发布时间】:2010-10-13 18:46:56 【问题描述】:

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

//start documentation

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

说明: 接收函数结果的数据结构。所有函数结果将是 存储为 Unicode (UTF-8)。

方法:

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

输入:

char * imgPath

此图像位置的完整路径 识别功能

RECO_DATA * o_data

接收函数的数据对象 结果。 函数返回: 成功则返回 true,否则返回 false。

//end documentation

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

导入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);

调用函数的代码:

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

我得到的错误是 ""在 DLL 'cnOCRsdk.dll' 中找不到名为 'recoCHN_P_Name' 的入口点。" 我怀疑我在将类型从 C++ 转换为 C# 时出错。但具体在哪里……?

【问题讨论】:

【参考方案1】:

首先确定函数是否被实际导出:

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

【讨论】:

我在输出中有一行写着“14 D 00007B40 ?recoCHN_P_Name@CcnOCRsdk@@QAE_NPADPAURECO_DATA@@@Z”这告诉我什么? 查看kegel.com/mangle.html了解如何解密的详细说明。确保数据类型正确。【参考方案2】:

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

extern "C" ...

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

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

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

我猜,关键是将入口点指定为“损坏的”名称

    [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);

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

【讨论】:

这会起作用,但如果函数(签名)发生任何变化,您必须更改损坏的名称。建议如上所述在 DLL 中使用extern "C" 定义它们。 @Goku,您可以使用名为 PE Explorer (heaventools.com/overview.htm) 的程序或 Visual Studio 附带的名为 dumpbin.exe 的程序找到它。【参考方案5】:

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

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

我在这些步骤中解决了同样的问题:步骤 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);

步骤 3) 构建并导出 DLL 文件,然后使用 Dependency Walker 软件获取您的函数 EntryPointstep4) 导入 DLL 文件在 C# 项目中,设置 EntryPointCallingConvention 变量如下:

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

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

【讨论】:

__declspec(dllexport) 对我来说很关键,another answer 有人用extern "C" 标记他们,但没有任何内容被导出,谢谢! 谢谢!我见过大约 10 种推荐使用“extern C”和“__declspec(dllexport)”的解决方案。 C++ 编译器不能与 extern 一起使用,但我无法找出原因。这对我来说是第一次。【参考方案8】:

当我们想要访问数据库时遇到了这个问题,并通过将 EF 核心更改为 EF 6.4.4 来解决它 可能是您遇到了这样的问题,需要更改或降级您的 EF 版本(如果您使用过 EF)

【讨论】:

【参考方案9】:

我们遇到了这个问题。我们将 EntityFramework.core 更改为 EntityFrameWork 6.4.4,之后程序运行良好。你最改变的是框架版本。

【讨论】:

以上是关于“无法在 dll 中找到名为 [function] 的入口点”(c++ 到 c# 类型转换)的主要内容,如果未能解决你的问题,请参考以下文章