![](/img/trans.png)
[英]Unable to find an entry point named xxx in mixed C++ DLL and WPF C# project
[英]"Unable to find an entry point named [function] in dll" (c++ to c# type conversion)
我有一个来自第三方的 dll,它是用 C++ 编写的。 以下是来自 dll 文档的一些信息:
//start documentation
RECO_DATA{
wchar_t Surname[200];
wchar_t Firstname[200];
}
描述:用于接收 function 结果的数据结构。 所有 function 结果将存储为 Unicode (UTF-8)。
方法:
bool recoCHN_P_Name(char *imgPath,RECO_DATA *o_data);
输入:
char * imgPath
此 function 要识别的图像位置的完整路径
RECO_DATA * o_data
数据 object 用于接收 function 结果。 Function 返回:成功则返回 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);
}
调用 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究竟在哪里……?
首先确保 function 实际导出:
在 Visual Studio 命令提示符中,使用dumpbin /exports whatever.dll
C# 不支持 C++ 名称修改,您需要声明 C++ 函数
extern "C" {...}
(如果它们来自第三方,则可能不是一个选项),或者如果您可以使其正常工作,则直接调用损坏的名称。 让第三方为功能提供未损坏的接口可能更容易。
解决了 - 至少到程序不会中断并且实际上返回一个布尔值的程度。
我猜,关键是将入口点指定为“损坏的”名称
[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);
之后我遇到了一些其他错误,但“无法找到入口点”消失了。
我在这些步骤中解决了同样的问题:
步骤 1)如果您使用 Visual Studio 在 C++ 中对自定义 DLL 进行编程,则在项目的属性页中将Common Language Runtime Support (/clr)
参数设置为Common Language Runtime Support (/clr)
。
步骤 2)在.h
文件中使用__declspec(dllexport)
关键字对 function 减速,如下所示:
__declspec(dllexport) double Sum(int a,int b);
步骤 3)构建并导出 DLL 文件,然后使用Dependency Walker软件获取您的 function EntryPoint 。
step4)导入 DLL 文件在 C# 项目中,设置EntryPoint和CallingConvention变量,如下所示:
[DllImport("custom.dll", EntryPoint = "?Sum@@YAXHHHHHHNNN@Z", CallingConvention = CallingConvention.Cdecl)]
public static extern double Sum(int a,int b);
我会使用 C++/CLI 编写一个包装器。 此包装器将能够包含 .h 文件并链接到您从第三方供应商处获得的 .lib 文件。 然后为您的 C# 程序编写托管接口既简单又安全。
可以在主非托管 dll 随附的“.lib”文件中找到正确的EntryPoint字符串。
当我们想要访问 DB 并通过将 EF 核心更改为 EF 6.4.4 来解决这个问题时,我们可能会遇到这样的问题,需要更改或降级您的 EF 版本(如果您使用过 EF)
我们遇到了这个问题。我们将 EntityFramework.core 更改为 EntityFrameWork 6.4.4,之后程序运行良好。 你最改变的是框架版本。
由于 DLL 和您的应用程序之间的字符串编组不匹配,您可能会收到此错误。 例如,一个使用ANSI,另一个是unicode。
你可以尝试这样的事情:
[DllImport("yourDLL.dll", CharSet = CharSet.Unicode )]
public static extern String YourFunction(String name);
在此处结帐以获取其他可能原因的列表。
您可以在 DllImport 中指定 CallingConvention 时尝试使用未损坏的名称
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.