簡體   English   中英

C#調用C ++ dll獲取EntryPointNotFoundException

[英]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); 聲明。

幾個問題:

  1. 我需要將該lib文件添加到我的C#項目的某個地方嗎? 怎么樣?

  2. 我需要將頭文件添加到我的C#項目中嗎? 怎么樣? (現在沒有編譯錯誤)

  3. 我想刪除那些"..\\\\..\\\\thirdParty\\\\cogs\\\\"硬編碼路徑。 怎么樣?

  4. 如何獲得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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM