[英]C# call a C++ dll get EntryPointNotFoundException
I was gaven a C++ dll file, a lib
file and a header file. 我是一个C ++ DLL文件,一个
lib
文件和一个头文件。 I need to call them from my C# application. 我需要从我的C#应用程序中调用它们。
header file looks like this: 头文件看起来像这样:
class Clog ;
class EXPORT_MACRO NB_DPSM
{
private:
string sFileNameToAnalyze ;
Clog *pLog ;
void write2log(string text) ;
public:
NB_DPSM(void);
~NB_DPSM(void);
void setFileNameToAnalyze(string FileNameToAnalyze) ;
int WriteGenbenchData(string& message) ;
};
In my C# code, I have those code: 在我的C#代码中,我有这些代码:
internal ReturnStatus correctDataDLL(string rawDataFileName)
{
if (rawDataFileName == null || rawDataFileName.Length <= 0)
{
return ReturnStatus.Return_CannotFindFile;
}
else
{
setFileNameToAnalyze(rawDataFileName);
}
string msg = "";
int returnVal = WriteGenbenchData(ref msg);
return ReturnStatus.Return_Success;
}
[DllImport("..\\..\\thirdParty\\cogs\\NB_DPSM.dll")]
public static extern void setFileNameToAnalyze(string fileName);
[DllImport("..\\..\\thirdParty\\cogs\\NB_DPSM.dll")]
public static extern int WriteGenbenchData(ref string message);
I got EntryPointNotFoundException
at the setFileNameToAnalyze(rawDataFileName);
我在
setFileNameToAnalyze(rawDataFileName);
得到了EntryPointNotFoundException
setFileNameToAnalyze(rawDataFileName);
statement. 声明。
Few questions: 几个问题:
do I need to add that lib
file into somewhere of my C# project? 我需要将该
lib
文件添加到我的C#项目的某个地方吗? how? 怎么样?
do I need to add the header file into my C# project? 我需要将头文件添加到我的C#项目中吗? how?
怎么样? (no compile error for now)
(现在没有编译错误)
I would like to remove those "..\\\\..\\\\thirdParty\\\\cogs\\\\"
hardcode path. 我想删除那些
"..\\\\..\\\\thirdParty\\\\cogs\\\\"
硬编码路径。 how to this? 怎么样?
how to get ride of that EntryPointNotFoundException
? 如何获得
EntryPointNotFoundException
?
thanks, 谢谢,
Place the functions outside any classes (as global functions) and in an extern "C" { ... }
block. 将函数放在任何类(作为全局函数)之外和
extern "C" { ... }
块中。
You don't need the header file in C#. 您不需要C#中的头文件。 (That's what the
[DllImport]
does) (这就是
[DllImport]
作用)
You don't need to include either the header file or the lib file in your C# project. 您不需要在C#项目中包含头文件或lib文件。 These files are useless to you anyway.
无论如何,这些文件对你来说都是无用的。
The reason you are getting an EntryPointNotFound exception is that you've provided incorrect names for those entry points. 您获得EntryPointNotFound异常的原因是您为这些入口点提供了错误的名称。 When you compile a C++ project, the compiler mangles the names by adding additional information about parameters and return types.
编译C ++项目时,编译器会通过添加有关参数和返回类型的其他信息来破坏名称。 (You can use the dumpbin.exe utility to see these entry points.)
(您可以使用dumpbin.exe实用程序查看这些入口点。)
The real problem, however, is that your DLL evidentally contains a C++ class. 然而,真正的问题是你的DLL显然包含一个C ++类。 "setFileNameToAnalyze" and "WriteGenbenchData" are instance methods of that class, not static functions.
“setFileNameToAnalyze”和“WriteGenbenchData”是该类的实例方法,而不是静态函数。 You can't call them without creating an instance of the NB_DPSM class first.
如果不首先创建NB_DPSM类的实例,则无法调用它们。
It might be possible to do that using only P/Invoke, but at this point I think it's likely more trouble than it's worth. 可能只使用P / Invoke来做到这一点,但此时我认为它可能比它的价值更麻烦。 You should create a managed C++ class library to wrap the old DLL instead.
您应该创建一个托管C ++类库来包装旧的DLL。
As to part (3) of your question, just remove the paths and make sure that NB_DPSM.dll resides in the same bin directory as the result of your output files. 至于问题的第(3)部分,只需删除路径并确保NB_DPSM.dll与输出文件的结果位于同一个bin目录中。
Could try make your own unmanaged C++ dll as a shim, using the provided dll have 1 method 可以尝试将自己的非托管C ++ DLL作为垫片,使用提供的dll有1个方法
extern "C" int GenBenchData( const string &filename, string & message ){
NB_DPSM builder;
builder.setFileNameToAnalyze(filename);
return builder.WriteGenbenchData( message );
}
in C# you declare that with 在C#中你声明了
[DllImport("shim.dll", CharSet = CharSet.Auto)]
static extern int GenBenchData([MarshalAs(UnmanagedType.LPStr)]string filename, StringBuilder message);
Also beware of the calling convention . 还要注意调用约定 。 If your DLL is really C++, use a tool to visualize the exported names (like depends.exe referred in the linked article).
如果您的DLL确实是C ++,请使用工具可视化导出的名称(如链接文章中提到的depends.exe)。 Each C++ compiler has its own decoration scheme what makes it a bit tedious to adapt.
每个C ++编译器都有自己的装饰方案,这使得它适应起来有点乏味。 Alternatively you can use a wrapper managed C++ assembly that links to the C++ DLL.
或者,您可以使用链接到C ++ DLL的包装器托管C ++程序集。 If it is just a C interface take care of the calling convention and the type sizes (common pitfall: a long in C# is 64bit in C/C++ it is 32bit)
如果它只是一个C接口,则需要考虑调用约定和类型大小(常见的陷阱:C#中的long长度为64位,C / C ++为32位)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.