![](/img/trans.png)
[英]EntryPointNotFoundException when binding C++ dll in C#
[英]C# call a C++ dll get EntryPointNotFoundException
我是一個C ++ DLL文件,一個lib
文件和一個頭文件。 我需要從我的C#應用程序中調用它們。
頭文件看起來像這樣:
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) ;
};
在我的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);
我在setFileNameToAnalyze(rawDataFileName);
得到了EntryPointNotFoundException
setFileNameToAnalyze(rawDataFileName);
聲明。
幾個問題:
我需要將該lib
文件添加到我的C#項目的某個地方嗎? 怎么樣?
我需要將頭文件添加到我的C#項目中嗎? 怎么樣? (現在沒有編譯錯誤)
我想刪除那些"..\\\\..\\\\thirdParty\\\\cogs\\\\"
硬編碼路徑。 怎么樣?
如何獲得EntryPointNotFoundException
?
謝謝,
將函數放在任何類(作為全局函數)之外和extern "C" { ... }
塊中。
您不需要C#中的頭文件。 (這就是[DllImport]
作用)
您不需要在C#項目中包含頭文件或lib文件。 無論如何,這些文件對你來說都是無用的。
您獲得EntryPointNotFound異常的原因是您為這些入口點提供了錯誤的名稱。 編譯C ++項目時,編譯器會通過添加有關參數和返回類型的其他信息來破壞名稱。 (您可以使用dumpbin.exe實用程序查看這些入口點。)
然而,真正的問題是你的DLL顯然包含一個C ++類。 “setFileNameToAnalyze”和“WriteGenbenchData”是該類的實例方法,而不是靜態函數。 如果不首先創建NB_DPSM類的實例,則無法調用它們。
可能只使用P / Invoke來做到這一點,但此時我認為它可能比它的價值更麻煩。 您應該創建一個托管C ++類庫來包裝舊的DLL。
至於問題的第(3)部分,只需刪除路徑並確保NB_DPSM.dll與輸出文件的結果位於同一個bin目錄中。
可以嘗試將自己的非托管C ++ DLL作為墊片,使用提供的dll有1個方法
extern "C" int GenBenchData( const string &filename, string & message ){
NB_DPSM builder;
builder.setFileNameToAnalyze(filename);
return builder.WriteGenbenchData( message );
}
在C#中你聲明了
[DllImport("shim.dll", CharSet = CharSet.Auto)]
static extern int GenBenchData([MarshalAs(UnmanagedType.LPStr)]string filename, StringBuilder message);
還要注意調用約定 。 如果您的DLL確實是C ++,請使用工具可視化導出的名稱(如鏈接文章中提到的depends.exe)。 每個C ++編譯器都有自己的裝飾方案,這使得它適應起來有點乏味。 或者,您可以使用鏈接到C ++ DLL的包裝器托管C ++程序集。 如果它只是一個C接口,則需要考慮調用約定和類型大小(常見的陷阱:C#中的long長度為64位,C / C ++為32位)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.