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

我有一个来自第三方的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 

用于接收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); } 

调用函数的代码:

  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#时遇到错误。但是究竟……?

首先确保实际导出该函数:

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

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

 extern "C" {...} 

(如果他们来自第三方,可能不是一个选项),或者如果你可以让它发挥作用,可以直接调用受损的名字。 让第三方为该function提供非破坏的界面可能更容易。

解决了 – 至少到程序没有破坏的程度并且实际上给我一个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); 

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

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

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

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

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

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

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

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

 [DllImport("custom.dll", EntryPoint = "?Sum@@YAXHHHHHHNNN@Z", CallingConvention = CallingConvention.Cdecl)] public static extern double Sum(int a,int b); 

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

可以在“.lib”文件中找到正确的EntryPoint字符串,该文件随主要的非托管dll一起提供。