簡體   English   中英

Dollnet核心的DllImport返回當前DLL的DLLNotFoundException

[英]DllImport for Dotnet core returning DLLNotFoundException for present DLL

在過去的幾天里,我一直在嘗試與Linux在dotnet核心中的C庫(為ARM平台構建)相接口。 我要做的就是調用一個簡單的函數,該函數(本質上)返回一個字符串。

但是,我沒有使用C#整體上使用DLLImport或interop的經驗,而且我很掙扎。

C代碼看起來像(在我使用工作平台時使用替代名稱):

int version(int argc, char *argv[])
{
    return READ_DATA(0,
            version, //callbackfunction
            "version: 0x%04x\n"); //formatting string
}
    public class Board
    {
        private Interop_Commands _commands = new Interop_Commands();

        public string GetVersion()
        {
            return _commands.GetVersion();
        }
    }
    internal class Interop_Commands
    {
        public const string LIBRARYPATH = "libname";
        [DllImport(LIBRARYPATH,CharSet=CharSet.Unicode, CallingConvention =CallingConvention.Cdecl)]
        public static extern int version(int argc, StringBuilder argv);

        public string GetVersion()
        {
            var sb = new StringBuilder();
            Console.WriteLine($"Calling {nameof(version)}");
            version(0, sb);
            Console.WriteLine($"Called {nameof(version)}, got: {sb.ToString()}");
            return sb.ToString();
        }
    }

與調用類(主要用於此非常簡單的概念/試驗代碼證明):

    static void Main(string[] args)
    {
        Console.WriteLine("Getting Version from board..");

        var board = new Board();
        Console.WriteLine(board.GetVersion());

        Console.WriteLine("done");
        Console.ReadLine();
    }

文件夾結構為(簡化):


|-> DLL /運行時
|-> libname(在這里注意不是.so,只是libname)

任何幫助將不勝感激,我發現C導入/用法的示例受到限制,並且還發現了有關如何在dotnet核心中使用自定義庫的示例受到限制。

編輯1:

在@Sohaib Jundi的幫助下,我添加了extern因此簽名現在是:(它不會使用extern“ C”進行編譯)

extern int version(int argc, char *argv[])

我不確定接下來要嘗試什么。

但是dotnet core不會在x86上發布並且目標運行時設置為linux-arm ,只會引發未知異常,並且日志文件不是很有幫助。如果我將編譯的庫與先前的代碼( AnyCPU + linux-arm )一起使用,那么仍然會拋出DllNotFoundException

*編輯2:*

事實證明,我使用的原始的無擴展名文件似乎是引用靜態庫的可執行文件(最終被編譯成可執行文件)。 重建我設法將靜態庫分開,但是仍然得到相同的DllNotFoundException 有人知道dotnet核心上DllImport的搜索過程是什么嗎?

互操作/導入代碼現在看起來像:

[DllImport("libname", 
           CallingConvention =CallingConvention.Cdecl,
           EntryPoint= "version")]
public static extern int version(ref uint val);

靜態庫代碼如下所示:

extern int version(uint32_t *);

經過一番游戲后,我設法得到了一個例子。
跟着這些步驟:
1.從dll中導出函數,即:將extern "C" __declspec(dllexport)到函數簽名中
2.確保dll和dotnet核心應用程序具有相同的體系結構。 不要將dotnet核心保留為“任何CPU”,而應將其強制為與dll相同的體系結構。 (項目屬性->構建->平台目標= x86或x64)

我找到了解決方法..該庫被編譯為.la (靜態鏈接庫)而不是.so (共享庫)庫。 DllImport不適用於靜態鏈接的庫,因此將庫重新編譯為共享庫意味着現在將找到dll(我也將LD_LIBRARY_PATH導出為pwd以確保它在搜索路徑中。)。

一旦進入,其余的代碼就位。 上面版本的匹配dll導入聲明是正確的(來自* EDIT 2 * )-使用ref uint 因此,現在我必須擴展我的互操作類支持的方法以完全支持該庫。

感謝您的幫助@Sohaib Jundi

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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